斐波那契堆(fibonacci heap)基础

斐波那契堆是由一组最小堆有序树组成,其中的每棵树都必须符合最小堆属性。 简单点,斐波那契堆是由一组有点特别的树组成。除了两个与元素删除有关的 操作(EXTRACT-MIN和DELETE)之外,它的其它操作都能在常数时间内完成。可 以看下斐波那契堆和二叉堆的运行时间对比表:

斐波那契堆的特点:不涉及删除元素的操作有O(1)的平摊时间。 Extract-Min和Delete的数目和其它相比较小时效率更佳。用途:稠密图每次Decrease-key只要O(1)的平摊时间,和二项堆的O(lgn)相比是巨大的改进。斐波那契堆的结构较二项堆更松散。因此对结构的维护可以到方便时再做。斐波那契堆中的树是有根而无序的。每个节点包含一个指向其父节点的指针p[x],以及一个指向其任一子女的指针child[x](指向子女双链表)。每个孩子有left[x]和right[x]。(意义:在O(1)的时间内去掉一个节点,或者在O(1)的时间内合并双链表。)其它域: degree[x]存储子女个数。 mark[x]指示自从x上一次成为另一节点的子女以来,它是否失掉一个孩子。一个给定的斐波那契堆可以通过一个指向其含有最小关键字树的指针来访问。斐波那契堆的关键思想在于尽量延迟对堆的维护。创建一个新的斐波那契堆: MAKE_Fib_Heap有O(1)的代价。插入一个节点:分三步进行: 1,,为新的节点置p,child,left,right,mark等域。时间消耗: O(1)。 2,将包含x的根表和根表H连接。时间消耗: O(1) 。3,在O(1)的时间内调整指向该堆的指针min[x] 时间消耗: O(1) 。以节点数表示势。势的增加为1,实际代价为O(1)。所以平摊代价为O(1)。寻找最小节点: min[x]指向的节点即为最小节点。因为势没有变化,所以这个操作的平摊代价为O(1)。合并两个斐波那契堆:分为3步: 1。合并根表 2。设置新的min[h] 3。重置n[x]。抽取最小节点:这是最复杂的工作。被延迟的对根表的调整工作最终由这个操作进行。 1。去掉最小值,将其每个孩子都加入根表。 2。将相同度数树的合并。调整根表的步骤 1。在根表中找出两个具有相同度数的根x和y,且key[x]《key[y] 2。将y与x连接。将y从根表里去掉,成为x一个孩子,并增加degree[x]。减小一个节点的权 1。若此减小不影响堆序,不作调整。 2。若影响堆序,则从堆中删除该节点,将其加入根表。并检查其父亲的mark位。若为false,则停止,并将其置为true。若为true,则删除其父亲,继续递归向上执行。直到一个节点mark域为false或该节点为根节点为止。删除一个节点: 1。将该节点权调整至最小 2。抽取最小值。证明最大度数界:证明删除或extract-min的平摊时间为O(lgn)。引理1:设x为斐波那契堆中任一节点,并假设degree[x]=k。设y1,y2,。。。yk表示按与x链接的次序排列的x的子女,从最早的到最迟的,则对i=2,3,…,k,有degree[y1]>=0且degree[yi]>=i-2 证明:显然degree[y1]》=0 对i>=2,注意到y1被链接到x上时,y1,y2,。。yi-1都是x的子女,故我们必有degree[x]>=i-1 又仅当degree[x]=degree[yi]时,才将yi链接到x上。故此时必有degree[yi>=i-1,在此之后,节点yi至多失去一个孩子,因为失去两个就被切断了。所以degree[yi]>=i-2引理2:对所有的整数k>=0,Fk+2=1+sum(Fi) [0<=i<=k] ,F为斐波那契数。用数学归纳法证明。并可证明不等式 Fk+2 >= G^k ,其中G为黄金分割率。 (1+5^0.5)/2=1.161803…引理3:设x为斐波那契堆中任一节点,并设k=degree[x],那么,size(x)>=Fk+2>=G^k。推论:在一个包含n个节点的斐波那契堆中节点的最大度数为O(lgn)。

旅行,重复一个承诺和梦想,听他第二十八次提起童年往事,

斐波那契堆(fibonacci heap)基础

相关文章:

你感兴趣的文章:

标签云: