斐波那契堆——精选推荐

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

斐波那契堆
本章内容:
⼀ 斐波那契堆结构
⼆ 可合并堆操作
三 关键字减值和删除⼀个结点
四 最⼤度数的界
可合并堆⽀持以下5种操作:
MAKE-HEAP():创建和返回⼀个新的空堆
INSERT(H,x):将⼀个含关键字的元素x插进堆H中
MINIMUN(H):返回⼀个指向堆H中具有最⼩关键字元素的指针
EXTRACT-MIN(H):从堆中删除最⼩关键字的元素,并返回⼀个指向该元素的指针
UNION(H1,H2):创建并返回⼀个包含2个堆中所有元素的新堆,并销毁原来2个堆
斐波那契堆除了以上的堆操作之外还⽀持以下2种操作:
DECREASE-KEY(H,x,k):将堆H中元素x的关键字赋予新值k,假定新值k不⼤于当前的关键字。

DELETE(H,x):从堆中删除元素x
可合并堆的运⾏时间
⼀ 斐波那契堆结构
1. 斐波那契堆是⼀系列具有最⼩堆序的有根树的集合,每棵树遵循最⼩堆的性质,即每个结点的关键字⼤于或等于⽗结点的关键字。

2. 每个结点x包含⼀个指向⽗结点的指针x.p和⼀个指向它的某⼀个孩⼦的指针x.child。

x的所有孩⼦被链接成⼀个双向的链表,称为x的孩⼦链表。

每个孩⼦y有指针y.left和y.right。

如果y是仅有的⼀个孩⼦,则y.left = y.right = y。

3. x.degree记录孩⼦的个数。

4. x.mark指⽰结点x⾃从上⼀次成为另⼀个结点的孩⼦后,是否失去过孩⼦。

新产⽣的结点是未被标记的。

5. H.min指向具有最⼩关键字的树的根结点。

6. H.n记录堆中所有结点的数⽬。

7. 所有树的根⽤其left和right链成⼀个环形的双链表,称为根链表。

8. 势函数:
t(H)表⽰根链表中树的数⽬,m(H)表⽰已标记的结点数⽬。

9. ⼀个例⼦
⼆ 可合并堆的操作
1. 插⼊⼀个结点x,x已经被分配且x.key已经被赋值:
该操作势的增加量为:
实际代价为O(1),摊还代价为O(1) + 1 = O(1)
2. 两个斐波那契堆的合并:
势函数变化为:
所以实际代价为O(1)
3. 抽取最⼩结点:
该过程⾸先将最⼩结点的每个孩⼦变成根结点,并从链表中删除该结点,然后通过CONSOLIDATE把具有相同度数的根结点合并来链接成新的根链表,直到每个度数⾄多只有⼀个根在根链表中。

合并相同度数的根结点:
把根结点y链接到x成为x的孩⼦:
4~14⾏遍历根链表,对根链表中的每个结点x,查找辅助数组A,如果没有相同度数的结点,则将该结点标记为该度数的结点。

如果已经存在,则将key值⼤的结点链接到⼩的上⾯,使x的degree加1,并继续判断是否有度数相同的结点。

这样14⾏之后A中记录的根链表将没有重复度数的根结点。

然后15~23⾏利⽤辅助数组A重建根链表。

抽取最⼩结点操作的摊还代价最多为O(D(n)),即与最⼤度数成正⽐。

后⾯将会证明D(n) = O(lg n),所以该操作的摊还代价为O(lg n).
三 关键字减值和删除⼀个结点
1. 关键字减值:
减值后如果没有违反最⼩堆序则⽆需改变,否则要在6~7⾏进⾏切断和级联切断操作。

回顾前⾯提到的结点的⼀个属性mark,在该结点成为根结点的时候置为false,在成为⼀个孩⼦结点并且失去⼀个孩⼦后置为true。

CUT函数⾸先切断x与⽗结点y的链接,并将x置为根结点,然后对其⽗结点y进⾏级联切断。

这⾥的规则是如果⼀个结点的mark为true并且失去⼀个孩⼦就要将其与⽗结点切断,意思就是当⼀个⾮根结点失去第⼆个孩⼦(失去第⼀个孩⼦时mark值变为true)的时候将其与⽗结点切断。

CASCADING-CUT就是通过递归操作⼀直往上切断,直到遇到根结点或者遇到⼀个未被标记的结点并将mark置为true。

可以证明FIB-HEAP-DECREASE-KEY的摊还代价为O(1).
2. 删除⼀个结点:
将最⼩关键字负⽆穷赋予x后即可通过FIB-HEAP-EXTRACT-MIN将其移除。

四 最⼤度数的界
1. 可以证明⼀个具有n个结点的斐波那契堆中任意结点的度数的上界D(n)为O(lg n),从⽽可以得到FIB-HEAP-EXTRACT-MIN和FIB-HEAP-DELETE操作摊还时间为O(lg n)。

相关文档
最新文档