查看“︁斐波那契堆”︁的源代码
←
斐波那契堆
跳转到导航
跳转到搜索
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
{{NoteTA |G1 = IT |1 = zh-cn:堆; zh-tw:堆積; |2 = zh-cn:二项堆; zh-tw:二項式堆積; zh-hk:二項堆積; }} {{Infobox data structure |name=斐波那契堆 |type=[[堆積]] |invented_by=[[邁克爾·弗雷德曼]]、[[罗伯特·塔扬]] |invented_year=1984年 |space_avg= |space_worst= |search_avg= |search_worst= |insert_avg=<math>\Theta(1)</math> |insert_worst= |delete_min_avg=<math>O(\log n)</math> |delete_min_worst= |find_min_avg=<math>\Theta(1)</math> |find_min_worst= |decrease_key_avg=<math>\Theta(1)</math> |decrease_key_worst= |merge_avg=<math>\Theta(1)</math> |merge_worst= }} '''斐波那契堆'''({{lang-en|Fibonacci heap}})是[[计算机科学]]中[[树 (数据结构)|树]]的集合。它比[[二项堆]]具有更好的[[平摊分析]]性能,可用于实现合并[[优先队列]]。不涉及删除元素的操作有 <math>O(1)</math> 的平摊时间。 Extract-Min和Delete的数目和其它相比,较小时效率更佳。稠密图每次decrease key只要 <math>O(1)</math> 的平摊时间,和二项堆的 <math>O(\log n)</math> 相比是巨大的改进。 斐波纳契堆于1984年由[[邁克爾·弗雷德曼]]与[[罗伯特·塔扬]]提出,1987年公开发表。<ref name="Fredman And Tarjan">{{cite journal|first1=Michael Lawrence|last1=Fredman|authorlink1=Michael Fredman|first2=Robert E.|last2=Tarjan|authorlink2=Robert Tarjan|title=Fibonacci heaps and their uses in improved network optimization algorithms|url=http://www.cl.cam.ac.uk/~sos22/supervise/dsaa/fib_heaps.pdf|format=PDF|journal=[[Journal of the Association for Computing Machinery]]|volume=34|year=1987|pages=596–615|ref=harv|doi=10.1145/28869.28874|issue=3|access-date=2013-11-20|archive-date=2016-06-23|archive-url=https://web.archive.org/web/20160623231902/http://www.cl.cam.ac.uk/~sos22/supervise/dsaa/fib_heaps.pdf|dead-url=no}}</ref>名字来源于运行时分析使用的[[斐波那契数]]。 ==结构== 斐波那契堆是由一组最小堆有序树构成的。每个節點的度数为其子節點的数目。树的度数为其根節點的度数。 斐波那契堆中的[[树 (图论)|树]]都是有根的但是无序。每个節點''x''包含指向父節點的指针''p[x]''和指向任意一个子節點的''child[x]''。x的所有子節點都用双向循环链表链接起来,叫做''x''的子链表。子链表中的每一个節點''y''都有指向它的左兄弟的''left[y]''和右兄弟的''right[y]''。如果節點''y''是''x''仅有的子節點,则''left[y]=right[y]=y''。 斐波那契堆中所有树的根節點也用一个双向循环链表链接起来。 使用一个指针指向斐波那契堆中最小元素。 ==操作== ===建立一个新的費波那契堆=== 此處範例中使用的程式語言為C 每个節點x的域 # 父節點p[x] # 指向任一子女的指针child[x]——節點x的子女被链接成一个环形双链表,称为x的子女表 # 左兄弟left[x] # 右兄弟right[x]——当left[x] = right[x] = x时,说明x是独子。 # 子女的个数degree[x] # 布尔值域mark[x]——标记是否失去了一个孩子 -{}- //斐波那契節點ADT typedef struct FibonacciHeapNode { int key; //節點 int degree; //度 FibonacciHeapNode *left; //左兄弟 FibonacciHeapNode *right; //右兄弟 FibonacciHeapNode *parent; //父節點 FibonacciHeapNode *child; //第一个孩子節點 bool marked; //是否被删除第1个孩子 } FibNode; 对于一个给定的斐波那契堆H,可以通过指向包含最小关键字的树根的指针min[H]来访问,这个節點被称为斐波那契堆中的最小節點。如果一个斐波那契堆H是空的,则min[H] = NIL. 在一个斐波那契堆中,所有树的根都通过left和right指针链接成一个环形的双向链表,称为堆的根表。于是,指针min[H]就指向根表中具有最小关键字的節點。 -{}- //斐波那契堆ADT typedef struct FibonacciHeap { int keyNum; //堆中節點个数 FibonacciHeapNode *min;//最小堆,根節點 int maxNumOfDegree; //最大度 FibonacciHeapNode **cons;//指向最大度的内存区域 } FibHeap; 创建一个空的費波那契堆,过程MAKE-FIB-HEAP 分配并返回一个費波那契堆对象H; -{}- //初始化一個空的Fibonacci Heap FibHeap *FibHeapMake() { return calloc(1, sizeof(FibHeap)); } //初始化節點x FibNode * FibHeapNodeMake() { FibNode *x = (FibNode *)calloc(1, sizeof(FibNode)); x->left = x->right = x; return x; } ===插入一个節點=== 创建一个仅包含一个節點的新的斐波纳契堆,然后执行堆合并。 ===查找最小的節點=== 由于用一个指针指向了具有最小值的根節點,因此查找最小的節點是簡單的操作。 ===合并两个斐波纳契堆=== 简单合并两个斐波纳契堆的根表。即把两个斐波纳契堆的所有树的根首尾衔接并置。 ===释放(删除)最小的節點=== 分为三步: # 查找最小的根節點并删除它,其所有的子節點都加入堆的根表,即它的子树都成为堆所包含的树; # 需要查找并维护堆的最小根節點,但这耗时较大。为此,同时完成堆的维护:对堆当前包含的树的度数从低到高,迭代执行具有相同度数的树的合并并实现最小树化调整,使得堆包含的树具有不同的度数。这一步使用一个数组,数组下标为根節點的度数,数组的值为指向该根節點指针。如果发现具有相同度数的其他根節點则合并两棵树并维护该数组的状态。 # 对当前堆的所有根節點查找最小的根節點。 ===降低一个節點的键值=== 对一个節點的键值降低后,自键值降低的節點开始自下而上的迭代执行下述操作,直至到根節點或一个未被标记(marked)節點为止: 如果当前節點键值小于其父節點的键值,则把该節點及其子树摘下来作为堆的新树的根節點;其原父節點如果是被标记(marked)節點,则也被摘下来作为堆的新树的根節點;如果其原父節點不是被标记(marked)節點且不是根節點,则其原父節點被加标记。 如果堆的新树的根節點被标记(marked),则去除该标记。 ===删除節點=== 把被删除節點的键值调整为负无穷小,然后执行“降低一个節點的键值”算法,然后再执行“删除最小節點”算法。 ==参考文献== <references/> {{Data structures}} {{计算机科学中的树}} [[Category:数据结构|F]] [[Category:堆]] [[Category:斐波那契数]]
该页面使用的模板:
Template:Cite journal
(
查看源代码
)
Template:Data structures
(
查看源代码
)
Template:Infobox data structure
(
查看源代码
)
Template:Lang-en
(
查看源代码
)
Template:NoteTA
(
查看源代码
)
Template:计算机科学中的树
(
查看源代码
)
返回
斐波那契堆
。
导航菜单
个人工具
登录
命名空间
页面
讨论
不转换
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
工具
链入页面
相关更改
页面信息