堆主要用于实现优先级队列。我们在以前的帖子中讨论了下面的堆。
二叉堆
二项堆
在时间复杂度方面,斐波那契堆优于二叉堆和二项堆。
以下是斐波那契堆的摊销时间复杂度。
1) Find Min: Θ(1) [Same as both Binary and Binomial]
2) Delete Min: O(Log n) [Θ(Log n) in both Binary and Binomial]
3) Insert: Θ(1) [Θ(Log n) in Binary and Θ(1) in Binomial]
4) Decrease-Key: Θ(1) [Θ(Log n) in both Binary and Binomial]
5) Merge: Θ(1) [Θ(m Log n) or Θ(m+n) in Binary and
Θ(Log n) in Binomial]
与二项式堆一样,斐波那契堆是具有最小堆或最大堆属性的树的集合。在斐波那契堆中,树可以具有任何形状,甚至所有树都可以是单个节点(这与二项式堆不同,其中每棵树都必须是二项式树)。
下面是取自此处的斐波那契堆示例。
Fibonacci Heap 维护一个指向最小值的指针(它是树的根)。所有树根都使用循环双向链表连接,因此可以使用单个“min”指针访问所有树根。
主要思想是以“懒惰”的方式执行操作。例如合并操作简单地链接两个堆,插入操作简单地添加一个具有单个节点的新树。操作提取最小值是最复杂的操作。它会延迟合并树木的工作。这使得删除也变得复杂,因为删除首先将键减少到负无穷大,然后调用提取最小值。
下面是一些关于斐波那契堆的有趣事实
- Decrease-Key 降低的时间复杂度在 Dijkstra 和 Prim 算法中很重要。对于二叉堆,这些算法的时间复杂度是 O(VLogV + ELogV)。如果使用Fibonacci Heap,则时间复杂度提高到O(VLogV + E)
- 尽管斐波那契堆在时间复杂度方面看起来很有希望,但在实践中发现它很慢,因为隐藏常数很高(来源 Wiki)。
- 之所以这样称呼斐波那契堆主要是因为在运行时间分析中使用了斐波那契数。此外,斐波那契堆中的每个节点的度数最多为 O(log n) 并且以度数为 k 的节点为根的子树的大小至少为 F k+2 ,其中 F k是第 k 个斐波那契数。
我们很快将详细讨论斐波那契堆操作。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。