二项堆gydF4y2Ba
一个gydF4y2Ba二项堆gydF4y2Ba是具体实现的吗gydF4y2Ba堆gydF4y2Ba数据结构。二项式堆是集合gydF4y2Ba二项树gydF4y2Ba每棵树都是一个有序的堆。在二项式堆中,有1棵或0棵二项式树gydF4y2Ba 在哪里gydF4y2Ba 帮助描述给定树可以拥有的元素数量:gydF4y2Ba .二项式堆类似于gydF4y2Ba二进制堆gydF4y2Ba但是二项堆具有更特定的结构,并允许有效地合并堆。堆通常用于实现gydF4y2Ba优先级队列gydF4y2Ba它们反过来用于许多类型的算法的实现,如gydF4y2Ba最短路径查找算法gydF4y2Ba-这些快速操作有助于使这些算法更有效。gydF4y2Ba
内容gydF4y2Ba
二项树gydF4y2Ba
二项式堆是由gydF4y2Ba二项树gydF4y2Ba.gydF4y2Ba
二叉树gydF4y2Ba 由两棵二叉树组成gydF4y2Ba 它们连在一起使得一个结点的根结点是另一个结点的最左子结点。gydF4y2Ba[2]gydF4y2Ba
二叉树的递归定义如下:gydF4y2Ba[3]gydF4y2Ba
- 0阶的二叉树是一个单节点。gydF4y2Ba
- k阶二叉树有一个根节点,其子结点是k−1、k−2、…阶二叉树的根。, 2,1,0(按此顺序)。gydF4y2Ba
下图是一个二叉树的集合,从左到右依次为0、1、2和3。顺序表示根节点可以有多少个子节点。例如,有三个子节点来自于3号节点,而没有子节点来自于0号节点。gydF4y2Ba
二叉树的性质gydF4y2Ba[4]gydF4y2Ba
一个订单gydF4y2Ba 二项树gydF4y2Ba 具有以下特性:gydF4y2Ba
- 树的高度是gydF4y2Ba .例如,在上图中,如果树只包含0gydF4y2Ba 阶节点,高度是gydF4y2Ba .因为整个树是有序的gydF4y2Ba ,高度为gydF4y2Ba
- 总共有gydF4y2Ba 树中的节点。gydF4y2Ba
- 树有gydF4y2Ba 深度节点gydF4y2Ba
- 根的次是gydF4y2Ba
- 删除根会得到gydF4y2Ba 二叉树:gydF4y2Ba
二项堆gydF4y2Ba
二项堆可以使用gydF4y2Ba双链表gydF4y2Ba来存储根节点。每个节点都存储有关父指针、左右兄弟指针、最左的子指针、它所拥有的子指针的数量以及它的键的信息。由于列表是双向链接的,父节点有指向子节点的指针,子节点也有指向父节点的指针。使用双链表允许常量时间插入和删除根列表,常量时间合并两个根列表,等等。gydF4y2Ba
二项堆的结构与gydF4y2Ba二进制数gydF4y2Ba系统。例如,一个二项式堆包含gydF4y2Ba 元素将包含有序的二叉树gydF4y2Ba 而且gydF4y2Ba 因为把十进制数字63写成二进制需要六位数字。63的二进制格式是111111。gydF4y2Ba
二项堆的性质gydF4y2Ba[4]gydF4y2Ba
对于二项堆gydF4y2Ba 节点,gydF4y2Ba
- 包含最小值元素的节点是任意一个的根gydF4y2Ba 或gydF4y2Ba
- 总的来说,堆已经gydF4y2Ba 二叉树;gydF4y2Ba
- 堆的高度为gydF4y2Ba
二项堆必须满足gydF4y2Ba二项堆性质gydF4y2Ba.其性质如下:gydF4y2Ba[3]gydF4y2Ba
二项堆属性gydF4y2Ba
二项最小堆中的每棵二项树都服从gydF4y2Ba最小堆属性gydF4y2Ba(一个节点的键值大于或等于它的父节点的键值),并且二项式Max堆中的每个二项式树都遵守gydF4y2Bamax-heap财产gydF4y2Ba(一个节点的键小于或等于它的父节点的键)。gydF4y2Ba
每一阶只能有1棵或0棵二叉树。换句话说,对于每一个gydF4y2Ba 时,最多有一棵二叉树gydF4y2Ba 在堆中。gydF4y2Ba
第一个属性确保在整个堆中保持min/max-heap属性。gydF4y2Ba
第二个性质意味着一个二项堆gydF4y2Ba 节点最多由gydF4y2Ba 二叉树,这是二叉堆的一个属性。gydF4y2Ba[2]gydF4y2Ba为了维护此属性,可能需要在操作之后对堆进行合并。例如,如果一个操作导致两个二阶堆,则必须采取步骤进行纠正,以保持二项堆属性。gydF4y2Ba
节点的子节点在双链表中链接在一起。每个子节点都有一个指向父节点的指针,父节点又有一个指向子节点的指针。这是上面的二项堆作为a的样子gydF4y2Ba链表gydF4y2Ba根的:gydF4y2Ba[6]gydF4y2Ba
最小功能gydF4y2Ba
下面是二项式堆如何实现堆的基本功能以及每个操作的时间复杂度。这些操作是用最小二项堆来描述的,但是可以很容易地适用于最大二项堆。gydF4y2Ba
找到最小gydF4y2Ba
使用gydF4y2Bafind-mingydF4y2Ba
函数查找堆中的最小元素,并查找根列表中的最小元素。最多只有gydF4y2Ba
树gydF4y2Ba
因此gydF4y2Ba
根gydF4y2Ba
所以检查一下列表gydF4y2Ba
求最小元素的根需要gydF4y2Ba
时间。gydF4y2Ba
哪些节点gydF4y2Ba
find-mingydF4y2Ba
函数搜索通过堆显示在上面的部分?gydF4y2Ba它将搜索包含树的根的链表。这个列表是gydF4y2Ba .gydF4y2Ba
合并gydF4y2Ba
二项堆gydF4y2Ba合并gydF4y2Ba
函数从gydF4y2Ba联盟gydF4y2Ba两个二项堆。二叉树的根节点是最小的元素。另一棵二叉树变成了新根的子树。比较要组合的树的根的键值,该节点将成为新树的根节点。gydF4y2Ba
例如,要合并下面的两个二叉树,请比较根节点。自gydF4y2Ba ,左边的黑色树(根节点7)附加到右边的灰色树(根节点3)作为子树。结果是一个3阶的树。gydF4y2Ba
合并操作的运行时间为gydF4y2Ba 在哪里gydF4y2Ba 两个堆中较大的一个中的节点数。gydF4y2Ba
合并二项式树gydF4y2Ba
下面是描述合并二项式树操作的伪代码。gydF4y2Ba[8]gydF4y2Ba
1 2 3 4 5gydF4y2Ba |
|
合并二项式堆gydF4y2Ba
下面是描述如何合并二项式堆的伪代码。gydF4y2Ba[8]gydF4y2Ba
1 2 3 4 5 6 7 8 9gydF4y2Ba |
|
解释了为什么gydF4y2Ba
合并gydF4y2Ba
需要gydF4y2Ba 时间。gydF4y2Ba合并gydF4y2Ba
在gydF4y2Ba 而且gydF4y2Ba 遍历根的链表gydF4y2Ba 而且gydF4y2Ba .让gydF4y2Ba 的节点数gydF4y2Ba 而且gydF4y2Ba 的节点数gydF4y2Ba .换句话说,它最多遍历gydF4y2Ba 节点。gydF4y2Ba运行时间与根列表中树的数量成正比。因此,它需要gydF4y2Ba 时间在最坏的情况下合并两个堆。gydF4y2Ba[10]gydF4y2Ba
提取最小gydF4y2Ba
此操作将删除二项堆中具有最小键的节点。要做到这一点,函数要找到根gydF4y2Ba
与gydF4y2Bafind-mingydF4y2Ba
函数,然后删除它。方法将原始堆拆分为两个,因此需要使用gydF4y2Ba合并gydF4y2Ba
函数。这个操作需要gydF4y2Ba
时间。gydF4y2Ba
下面是描述如何删除或提取最小元素的伪代码。gydF4y2Ba[8]gydF4y2Ba
1 2 3 4 5 6 7 8gydF4y2Ba |
|
插入gydF4y2Ba
插入gydF4y2Ba
取一个二项堆gydF4y2Ba
和insert元素gydF4y2Ba
进去。它创建了一个新的堆gydF4y2Ba
和插入gydF4y2Ba
进去。然后就合并了gydF4y2Ba
而且gydF4y2Ba
来获得最终的组合堆。gydF4y2Ba
这个操作需要gydF4y2Ba
时间,但平摊时间gydF4y2Ba插入gydF4y2Ba
是gydF4y2Ba
.gydF4y2Ba
删除gydF4y2Ba
取一个元素gydF4y2Ba
.如果gydF4y2Ba
在堆中,使用gydF4y2Ba降低关键gydF4y2Ba
函数设置的值gydF4y2Ba
的键到负无穷,并使用gydF4y2Ba取出最小值gydF4y2Ba
函数。gydF4y2Ba
该操作的运行时间为gydF4y2Ba .gydF4y2Ba
降低关键gydF4y2Ba
这个函数接受一个元素gydF4y2Ba 从二项堆中取出,并将其键值减到gydF4y2Ba .如果gydF4y2Ba 是二叉树吗gydF4y2Ba ,反复交换gydF4y2Ba 直到堆顺序恢复。gydF4y2Ba
该操作的运行时间为gydF4y2Ba .gydF4y2Ba
实现gydF4y2Ba
下面是二项式堆的伪代码实现:gydF4y2Ba[11]gydF4y2Ba[2]gydF4y2Ba
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101gydF4y2Ba |
|
二项式堆的Python实现比这个伪代码长得多。可以找到一些Python实现的示例gydF4y2Ba在这里gydF4y2Ba,gydF4y2Ba在这里gydF4y2Ba,gydF4y2Ba在这里gydF4y2Ba.gydF4y2Ba
二项堆的运行时间摘要gydF4y2Ba
操作gydF4y2Ba | 运行时间gydF4y2Ba |
插入gydF4y2Ba | |
删除gydF4y2Ba | |
找到最小值gydF4y2Ba | |
取出最小值gydF4y2Ba | |
降低关键gydF4y2Ba | |
合并gydF4y2Ba |
另请参阅gydF4y2Ba
参考文献gydF4y2Ba
- , L。gydF4y2Ba二项Trees.svggydF4y2Ba.检索2016年6月5日,从gydF4y2Bahttps://en.wikipedia.org/wiki/File:Binomial_Trees.svggydF4y2Ba
- Cormen, T., Leiserson, C., Rivest, R., & Stein, C.(2001)。gydF4y2Ba算法简介(第二版)gydF4y2Ba(页455 - 475)。麻省理工学院出版社。gydF4y2Ba
- ,。gydF4y2Ba二项堆gydF4y2Ba.检索2016年6月7日,从gydF4y2Bahttps://en.wikipedia.org/wiki/Binomial_heapgydF4y2Ba
- 韦恩,K。gydF4y2Ba二项堆gydF4y2Ba.检索2016年6月5日,从gydF4y2Bahttps://www.cs.princeton.edu/~wayne/kleinberg-tardos/pdf/BinomialHeaps.pdfgydF4y2Ba
- D。gydF4y2Ba二项堆- 13. svggydF4y2Ba.检索2016年6月5日,从gydF4y2Bahttps://en.wikipedia.org/wiki/File:Binomial-heap-13.svggydF4y2Ba
- 加勒斯D。gydF4y2Ba二项式希普斯;斐波那契堆gydF4y2Ba.检索2016年6月7日,从gydF4y2Bahttp://www.cs.usfca.edu/~galles/cs673/lecture/lecture13.printable.pdfgydF4y2Ba
- , L。gydF4y2Ba二项式堆合并1.svggydF4y2Ba.检索2016年6月7日,从gydF4y2Bahttps://en.wikipedia.org/wiki/File:Binomial_heap_merge1.svggydF4y2Ba
- ,。gydF4y2Ba二项堆gydF4y2Ba.检索2016年6月7日,从gydF4y2Bahttps://en.wikipedia.org/wiki/Binomial_heapgydF4y2Ba
- , L。gydF4y2Ba二项式堆合并2.svggydF4y2Ba.检索2016年6月7日,从gydF4y2Bahttps://en.wikipedia.org/wiki/File:Binomial_heap_merge2.svggydF4y2Ba
- 克鲁格,R。gydF4y2Ba第二周的课程总结gydF4y2Ba.检索2016年6月26日,从gydF4y2Bahttp://www.cs.toronto.edu/~krueger/cscB63h/lectures/lec02.txtgydF4y2Ba
- S. Stergiopoulos。gydF4y2Ba二项堆运算的算法gydF4y2Ba.检索2016年6月7日,从gydF4y2Bahttp://www.cse.yorku.ca/~aaw/Sotirios/BinomialHeapAlgorithm.htmlgydF4y2Ba