“邻接表实现一轮至多取出 $n$ 个最大键,并随边扫描增大至多 $O(m)$ 次键。采用反转比较方向的Fibonacci 堆,取最大为摊还 $O(\log n)$、增键为摊还 $O(1)$,得…”
形式陈述
结构与接口
作为一种可合并优先队列,Fibonacci 堆用有限的有根树组成森林,每棵树满足父键不大于子键。空堆的根表为空,最小根指针也为空;find-min 与 delete-min 要求堆非空。所有根放在双向循环链表中,并维护最小根指针;节点记录 degree、parent、child 和 mark。insert 添加单节点根,meld 拼接根链表,二者实际
decrease-key
势能分析
取
其中
这一下降支付与
degree 上界
设节点
令
单节点情形
直觉
Fibonacci 堆把原本每次更新都做的整理延迟到 delete-min:新增根暂不合并,减键只切断已经第二次失去孩子的松弛节点。根数和 mark 数记录了尚未偿还的结构债务;consolidation 与级联切断真正发生时,势能下降支付这批延迟工作。
例子与边界
级联切断例子与边界
设非根节点
insert 与 meld 的根表操作本身为最坏常数时间;decrease-key 与 delete-min 的主要保证则是摊还界。单次 delete-min 可处理线性多个根,单次 decrease-key 也可能沿长祖先链级联切断。指针布局和分配成本还会影响实际速度,不能只看渐近表判断工程优势。
完整成本表与删除
在节点分配与局部指针操作按常数成本计算的模型中,make-heap、find-min、insert、meld 的最坏实际成本为
Consolidation 使用按 degree 索引的临时数组,数组长度来自 degree bound。链接同度根时较小键成为父,另一根失去根身份并清 mark;遗漏清 mark 会让势能和级联语义同时出错。最小指针在根表重建过程中也必须重新扫描更新。
推论与应用
从接口到 Dijkstra 的成本
用邻接表实现非负权图上的 Dijkstra 算法,并为每个活动顶点维护稳定句柄。至多
这个推导依赖本页势能法给出的整段操作成本,不把某次较慢的调用变成快速调用。若改用重复插入距离记录、弹出后忽略旧记录的接口,就不再直接使用这份减键计数;内存占用与弹出次数也必须重新分析。
有根树的最大度为
参考资料
-
Michael L. Fredman、Robert Endre Tarjan,Fibonacci Heaps and Their Uses in Improved Network Optimization Algorithms,Journal of the ACM 34(3), 1987,pp. 596–615,§2:基本结构、删除与摊还界。
-
Thomas H. Cormen、Charles E. Leiserson、Ronald L. Rivest、Clifford Stein,Introduction to Algorithms, 3rd ed., MIT Press, 2009,Chapter 19。
-
David Karger,Fibonacci Heaps,MIT 6.854,2021,§1.1 的级联势能与按存留孩子链接次序的度数证明。