斐波那契堆
结构
斐波那契堆是由一组最小堆有序树构成的。每个节点的度数为其子节点的数目。树的度数为其根节点的度数。
斐波那契堆中的树都是有根的但是无序。每个节点x包含指向父节点的指针p[x]和指向任意一个子结点的child[x]。x的所有子节点都用双向循环链表链接起来,叫做x的子链表。子链表中的每一个节点y都有指向它的左兄弟的left[y]和右兄弟的right[y]。如果节点y是x仅有的子节点,则left[y]=right[y]=y。
斐波那契堆中所有树的根节点也用一个双向循环链表链接起来。
使用一个指针指向斐波那契堆中最小元素。
操作
建立一个新的斐波纳契堆
每个结点x的域
父节点p[x]
指向任一子女的指针child[x]——结点x的子女被链接成一个环形双链表,称为x的子女表
左兄弟left[x]
右兄弟right[x]——当left[x] = right[x] = x时,说明x是独子。
子女的个数degree[x]
布尔值域mark[x]——标记是否失去了一个孩子
对于一个给定的斐波那契堆H,可以通过指向包含最小关键字的树根的指针min[H]来访问,这个结点被称为斐波那契堆中的最小结点。如果一个斐波那契堆H是空的,则min[H] = NIL. 在一个斐波那契堆中,所有树的根都通过left和right指针链接成一个环形的双向链表,称为堆的根表。于是,指针min[H]就指向根表中具有最小关键字的结点。
创建一个空的斐波那契堆,过程MAKE-FIB-HEAP 分配并返回一个斐波那契堆对象H;
插入一个节点
创建一个仅包含一个节点的新的斐波纳契堆,然后执行堆合并。
查找最小的节点
由于用一个指针指向了具有最小值的根节点,因此查找最小的节点是简单的操作。
合并两个斐波纳契堆
简单合并两个斐波纳契堆的根表。即把两个斐波纳契堆的所有树的根首尾衔接并置。
释放(删除)最小的节点
分为三步:
查找最小的根节点并删除它,其所有的子节点都加入堆的根表,即它的子树都成为堆所包含的树;
需要查找并维护堆的最小根节点,但这耗时较大。为此,同时完成堆的维护:对堆当前包含的树的度数从低到高,迭代执行具有相同度数的树的合并并实现最小树化调整,使得堆包含的树具有不同的度数。这一步使用一个数组,数组下标为根节点的度数,数组的值为指向该根节点指针。如果发现具有相同度数的其他根节点则合并两棵树并维护该数组的状态。
对当前堆的所有根节点查找最小的根节点。
降低一个节点的键值
对一个节点的键值降低后,自键值降低的节点开始自下而上的迭代执行下述操作,直至到根节点或一个未被标记(marked)节点为止:
如果当前节点键值小于其父节点的键值,则把该节点及其子树摘下来作为堆的新树的根节点;其原父节点如果是被标记(marked)节点,则也被摘下来作为堆的新树的根节点;如果其原父节点不是被标记(marked)节点且不是根节点,则其原父节点被加标记。
如果堆的新树的根节点被标记(marked),则去除该标记。
删除节点
把节点的键值调整为负无穷小,然后执行“降低一个节点的键值”算法,然后再执行“删除最小节点”算法。
免责声明:以上内容版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。感谢每一位辛勤著写的作者,感谢每一位的分享。
- 有价值
- 一般般
- 没价值