【问题标题】:binary heap vs binomial heap vs fibonacci heap, regarding performance for a priority queue二叉堆 vs 二项堆 vs 斐波那契堆,关于优先级队列的性能
【发布时间】:2011-12-02 07:28:10
【问题描述】:

在标题中提到的那些中,有人可以解释一下我应该如何决定是使用一个堆实现还是另一个堆实现?

我想要一个答案来指导我根据问题选择有关结构性能的实现。现在,我正在做一个优先级队列,但我不仅想知道最适合这种情况的实现,还想知道允许我在任何其他情况下选择实现的基础......

要考虑的另一件事是我这次使用的是 haskell,所以,如果您知道任何技巧或可以改进这种语言的实现的东西,请告诉我!但是和以前一样,也欢迎使用其他语言的cmets!

谢谢!如果问题太基本,对不起,但我根本不熟悉堆。这是我第一次面临实施一个任务...

再次感谢!

【问题讨论】:

标签: performance haskell fibonacci binary-heap binomial-heap


【解决方案1】:

您可能会在http://themonadreader.files.wordpress.com/2010/05/issue16.pdf 中找到相关的第三篇文章。

【讨论】:

  • 在第 45 页的第三篇文章中,当他们定义 data Succ rk a = BinomTree rk a ? rk a 时,在第二个 rk a 之前有一个有趣的符号,比如一个平躺的三角形(而不是我写的“?”符号)...我不太习惯haskell语法,你能解释一下那个符号是什么意思吗?谢谢!
  • @Throoze:奇怪的三角形只是Succ 类型的中缀数据构造函数。您可以将该行解读为:data Succ rk a = Succ (BinomTree rk a) (rk a)
  • 这只是一个符号,让论文更具可读性。在编写实际程序时,我通常会编写中缀构造函数 ":<: opqdonut>
  • (另外,完全披露:我是那篇文章的作者。)
【解决方案2】:

首先,您不会在 Haskell 中实现标准堆。相反,您将实现 persistentfunctional 堆。有时经典数据结构的功能版本与原始数据结构一样高效(例如简单的二叉树),但有时则不然(例如简单的队列)。在后一种情况下,您将需要一个专门的函数式数据结构。

如果你不熟悉函数式数据结构,我建议从 Okasaki 的伟大 bookthesis 开始(感兴趣的章节:至少 6.2.2、7.2.2)。


如果所有这些都超出了您的想象,我建议从实现一个简单的 linked 二进制堆开始。 (在 Haskell 中创建一个高效的基于数组的二叉堆有点乏味。)一旦完成,您可以尝试使用 Okasaki 的伪代码甚至从头开始来实现二叉堆。

PS。 This cstheory.se answer is great

【讨论】:

    【解决方案3】:

    它们对优先队列的不同操作具有不同的时间复杂度。这是给你的可视化表格

    ╔══════════════╦═══════════════════════╦════════════════════════╦══════════════════════════════╗
    ║  Operation   ║       Binary          ║      Binomial          ║       Fibonacci              ║
    ╠══════════════╬═══════════════════════╬════════════════════════╬══════════════════════════════╣
    ║              ║                       ║                        ║                              ║
    ║   insert     ║      O(logN)          ║      O(logN)           ║         O(1)                 ║
    ║              ║                       ║                        ║                              ║
    ╠══════════════╬═══════════════════════╬════════════════════════╬══════════════════════════════╣
    ║              ║                       ║                        ║                              ║
    ║  find Min    ║       O(1)            ║      O(logN)           ║         O(1)                 ║
    ║              ║                       ║                        ║                              ║
    ╠══════════════╬═══════════════════════╬════════════════════════╬══════════════════════════════╣
    ║              ║                       ║                        ║                              ║
    ║   Revmove    ║       O(logN)         ║      O(logN)           ║        O(logN)               ║
    ║              ║                       ║                        ║                              ║
    ╠══════════════╬═══════════════════════╬════════════════════════╬══════════════════════════════╣
    ║              ║                       ║                        ║                              ║
    ║ Decrease Key ║       O(logN)         ║      O(logN)           ║        O(1)                  ║
    ║              ║                       ║                        ║                              ║
    ╠══════════════╬═══════════════════════╬════════════════════════╬══════════════════════════════╣
    ║              ║                       ║                        ║                              ║
    ║    Union     ║         O(N)          ║      O(logN)           ║        O(1)                  ║
    ║              ║                       ║                        ║                              ║
    ╠══════════════╬═══════════════════════╬════════════════════════╬══════════════════════════════╣
    ║              ║ ■ Min element is root ║order k binomial tree Bk║ ■ Set of heap-ordered trees. ║
    ║              ║ ■ Heap height = logN  ║ ■ Number of nodes = 2k.║ ■ Maintain pointer to min.   ║
    ║              ║                       ║ ■ Height = k.          ║   (keeps find min/max O(1))  ║                        
    ║              ║                       ║ ■ Degree of root = k.  ║ ■ Set of marked nodes.       ║
    ║  Useful      ║                       ║ ■ Deleting root yields ║   (keep the heaps flat)      ║
    ║  Properties  ║                       ║   binomial trees       ║                              ║
    ║              ║                       ║   Bk-1, … , B0.        ║                              ║
    ║              ║                       ║   (see graph below)    ║                              ║
    ║              ║                       ║                        ║                              ║
    ║              ║                       ║                        ║                              ║
    ║              ║                       ║                        ║                              ║
    ║              ║                       ║                        ║                              ║             
    ╚══════════════╩═══════════════════════╩════════════════════════╩══════════════════════════════╝
    

    我从Princeton lecture slides得到这张图片

    二叉堆:


    二项式堆:


    斐波那契堆:

    注意:二项式堆和斐波那契堆看起来很熟悉,但它们有细微的不同:

    • 二项式堆:每次插入后急切地合并树。
    • 斐波那契堆:延迟合并直到下一个删除分钟。

    【讨论】:

      【解决方案4】:

      对功能二项式堆、斐波那契堆和配对堆的一些参考: https://github.com/downloads/liuxinyu95/AlgoXY/kheap-en.pdf

      如果性能确实是问题,我建议使用配对堆。唯一的风险是它的性能到目前为止仍然是一个猜想。但实验表明性能相当不错。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-14
        • 2017-10-18
        • 2012-12-29
        • 2011-04-15
        • 1970-01-01
        • 2012-12-16
        • 1970-01-01
        • 2010-11-24
        相关资源
        最近更新 更多