在 ざい 计算机 つくえ 科学 かがく 中 なか ,二 に 项堆 (英語 えいご :Binomial heap )是 ぜ 一种类似于二 に 叉 また 堆 うずたか 的 てき 堆 うずたか 结构 。与 あずか 二 に 叉 また 堆 うずたか 相 しょう 比 ひ ,其优势是可 か 以快速 そく 合 ごう 并两个堆,因 いん 此它属 ぞく 于可合 あい 并堆(mergeable heap )抽象 ちゅうしょう 数 すう 据 すえ 类型的 てき 一 いち 种。
二 に 项树[ 编辑 ]
二项树递归定义如下:
度数 どすう 为0的 てき 二项树只包含一个節点
度数 どすう 为k的 てき 二项树有一个根節点,根 ね 節点 せってん 下 か 有 ゆう
k
{\displaystyle k}
个子女 おんな ,每 まい 个子女 おんな 分 ぶん 别是度数 どすう 分 ぶん 别为
k
−
1
,
k
−
2
,
.
.
.
,
2
,
1
,
0
{\displaystyle k-1,k-2,...,2,1,0}
的 てき 二 に 项树的 てき 根 ね
二 に 项树(从左至 いたり 右 みぎ 度数 どすう 分 ぶん 别为0至 いたり 3
度数 どすう 为k的 てき 二 に 项树共有 きょうゆう
2
k
{\displaystyle 2^{k}}
个節点 てん ,高度 こうど 为
k
{\displaystyle k}
。在 ざい 深度 しんど d处有
(
k
d
)
{\displaystyle {\tbinom {k}{d}}}
(二 に 项式系 けい 数 すう )个節点 てん 。
度数 どすう 为k的 てき 二项树可以很容易从两颗度数为k-1的 てき 二项树合并得到:把 わ 一 いち 颗度数 すう 为k-1的 てき 二项树作为另一颗原度数为k-1的 てき 二项树的最左子树。这一性质是二项堆用于堆合并的基础。
二 に 项堆[ 编辑 ]
二项堆是指满足以下性质的二项树的集合:
每 まい 棵二项树都满足最小 さいしょう 堆 うずたか 性 せい 质 ,即 そく 節点 せってん 关键字 じ 大 だい 于等于其父 ちち 節点 せってん 的 てき 值
不能 ふのう 有 ゆう 两棵或 ある 以上 いじょう 的 てき 二项树有相同度数(包括 ほうかつ 度数 どすう 为0)。换句话说,具有 ぐゆう 度数 どすう k的 てき 二 に 项树有 ゆう 0个或1个。
以上 いじょう 第 だい 一个性质保证了二项树的根節点包含了最小的关键字。第 だい 二个性质则说明節点数为
n
{\displaystyle n}
的 てき 二项堆最多只有
log
n
{\displaystyle \log {n}}
棵二 に 项树。实际上 じょう ,包含 ほうがん n个节点 てん 的 てき 二项堆的构成情况,由 よし n的 てき 二进制表示唯一确定,其中每 ごと 一位对应于一颗二项树。例 れい 如,13的 てき 二进制表示为1101,
2
3
+
2
2
+
2
0
{\displaystyle 2^{3}+2^{2}+2^{0}}
, 因 いん 此具有 ぐゆう 13个节点 てん 的 てき 二项堆由度数为3, 2, 0的 てき 三棵二项树组成:
示 しめせ 例 れい :一 いち 个含13个節点 てん 的 てき 二 に 项堆
二 に 项堆的 てき 操作 そうさ [ 编辑 ]
由 よし 于并不 ふ 需要 じゅよう 对二项树的根節点进行随 ずい 机 つくえ 存 そん 取 と ,因 いん 而这些節点 てん 可 か 以存成 なり 链表 结构。
合 ごう 并[ 编辑 ]
合 ごう 并分支度 したく 相 しょう 同 どう 的 てき 二 に 项树
合 ごう 并两个二 に 项堆示 しめせ 例 れい ,实际上 じょう 把 わ 两棵分 ぶん 支度 じたく 为1的 てき 二项树合并为一棵分支度为2的 てき 二 に 项树。
最 さい 基本 きほん 的 てき 为二个分支度相同的二项树的合并。由 よし 于二项树根節點包含最小的关键字,因 いん 此在二棵树合并时,只 ただ 需比较二个根節點关键字的大小,其中含小关键字 じ 的 てき 節點 せってん 成 なり 为结果 はて 树的根 ね 節點 せってん ,另一棵树则变成结果树的子树。
function mergeTree(p, q)
if p.root <= q.root
return p.addSubTree(q)
else
return q.addSubTree(p)
两个二项堆的合并则可按如下步骤进行:分 ぶん 支度 したく
j
{\displaystyle j}
从小取 と 到 いた 大 だい ,在 ざい 两个二项堆中如果其中只有一棵树的分支度为
j
{\displaystyle j}
,即 そく 将 はた 此树移 うつり 动到结果堆 うずたか ,而如果 はて 只 ただ 两棵树的分 ぶん 支度 したく 都 と 为
j
{\displaystyle j}
,则根据 すえ 以上 いじょう 方法 ほうほう 合 あい 并为一 いち 个分支度 じたく 为
j
+
1
{\displaystyle j+1}
的 てき 二 に 项树。此后这个分 ぶん 支度 じたく 为
j
+
1
{\displaystyle j+1}
的 てき 树将可能 かのう 会 かい 和 わ 其他分 ぶん 支度 じたく 为
j
+
1
{\displaystyle j+1}
的 てき 二项树进行合并。因 よし 此,对于任 にん 何 なん 分 ふん 支度 じたく j,可能 かのう 最多 さいた 需要 じゅよう 合 あい 并3棵二 に 项树。
此操作 そうさ 的 てき 时间复杂度 ど 为
O
(
log
n
)
{\displaystyle {O}(\log n)}
。
function merge(p, q)
while not (p.end() and q.end())
tree = mergeTree(p.currentTree(), q.currentTree())
if not heap.currentTree().empty()
tree = mergeTree(tree, heap.currentTree())
heap.addTree(tree)
heap.next(); p.next(); q.next()
插入 そうにゅう [ 编辑 ]
创建一个只包含要插入元素的二项堆,再 さい 将 しょう 此堆与原 よはら 先 さき 的 てき 二项堆进行合并,即 そく 可 か 得 え 到 いた 插入 そうにゅう 后 きさき 的 てき 堆 うずたか 。由 よし 于需要 よう 合 ごう 并,插入 そうにゅう 操作 そうさ 需要 じゅよう
O
(
log
n
)
{\displaystyle {O}(\log n)}
的 てき 时间。平 ひら 摊分析 ぶんせき 的 てき 时间复杂度 ど 为
O
(
1
)
{\displaystyle {O}(1)}
。
查找最小 さいしょう 关键字 じ 所在 しょざい 節点 せってん [ 编辑 ]
由 よし 于满足 あし 最小 さいしょう 堆 うずたか 性 せい 质,只 ただ 需查找二项树的的根節点即可,因 いん 为一共有 きょうゆう
log
n
{\displaystyle \log n}
棵子树,所以 ゆえん 用 よう 所 しょ 时间为
O
(
log
n
)
{\displaystyle {O}(\log n)}
。
可 か 以保存 ほぞん 一个指向最小元素的指针,使 つかい 得 とく 查找最小 さいしょう 关键字 じ 所在 しょざい 節点 せってん 需要 じゅよう
O
(
1
)
{\displaystyle {O}(1)}
的 てき 时间。在 ざい 执行其他操作 そうさ 时,需要 じゅよう 修 おさむ 改 あらため 该指针。
删除最小 さいしょう 关键字 じ 所在 しょざい 節点 せってん [ 编辑 ]
先 さき 找到最小 さいしょう 关键字 じ 所在 しょざい 節点 せってん ,然 しか 后 きさき 将 はた 它从其所在 しょざい 的 てき 二 に 项树中 ちゅう 删除,并获得 とく 其子树。将 はた 这些子 こ 树看作 さく (合 ごう 并为)一 いち 个独立 どくりつ 的 てき 二 に 项堆,再 さい 将 しょう 此堆合 あい 并到原 ばら 先 さき 的 てき 堆 うずたか 中 なか 即 そく 可 か 。由 よし 于每棵树最多 さいた 有 ゆう
log
n
{\displaystyle \log n}
棵子树,创建新 しん 堆 うずたか 的 てき 时间为
O
(
log
n
)
{\displaystyle {O}(\log n)}
。同 どう 时合并堆的 てき 时间也为
O
(
log
n
)
{\displaystyle {O}(\log n)}
,故 こ 整 せい 个操作 そうさ 所 しょ 需时间为
O
(
log
n
)
{\displaystyle {O}(\log n)}
。
function deleteMin(heap)
min = heap.trees().first()
for each current in heap.trees()
if current.root < min then min = current
for each tree in min.subTrees()
tmp.addTree(tree)
heap.removeTree(min)
merge(heap, tmp)
减小特定 とくてい 節點 せってん (關 せき 鍵 かぎ 字 じ )的 てき 值(Decreasing a key) [ 编辑 ]
在 ざい 减小特定 とくてい 節點 せってん (關 せき 鍵 かぎ 字 じ )的 てき 值后,可能 かのう 会 かい 不 ふ 满足最小 さいしょう 堆積 たいせき 性 せい 质。此时,将 はた 其所在 ざい 節点 せってん 与 あずか 父 ちち 節点 せってん 交换,如还不 ふ 满足最小 さいしょう 堆 うずたか 性 せい 质则再 さい 与 あずか 祖父 そふ 節点 せってん 交换……直 ちょく 到 いた 最小 さいしょう 堆 うずたか 性 せい 质得到 いた 满足。操作 そうさ 所 しょ 需时间为
O
(
log
n
)
{\displaystyle {O}(\log n)}
。
将 はた 需要 じゅよう 删除的 てき 節点 せってん 的 てき 关键字 じ 的 てき 值减小 しょう 到 いた 负无穷大(比 ひ 二项堆中的其他所有关键字的值都小即可),执行“减小关键字 じ 的 てき 值”算法 さんぽう ,使 つかい 其调整 せい 到 いた 当 とう 前 まえ 二项树的根节点位置,再 さい 删除最小 さいしょう 关键字 じ 的 てき 根 ね 節点 せってん 即 そく 可 か 。
运行时间 [ 编辑 ]
以下 いか 对于二项堆操作的运行时间都为
O
(
log
n
)
{\displaystyle {O}(\log n)}
(節點 せってん 数 すう 为
n
{\displaystyle n}
):
在 ざい 二项堆中插入新節点
查找最小 さいしょう 关键字 じ 所在 しょざい 節点 せってん
从二项堆中删除最小关键字所在節点
减小给定節点 せってん 关键字 じ 的 てき 值
删除给定節点 せってん
合 ごう 并两个二 に 项堆
参 まいり 见[ 编辑 ]
参考 さんこう 资料[ 编辑 ]
外部 がいぶ 链接[ 编辑 ]