12

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

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

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

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

再次感谢!

4

4 回答 4

4

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

于 2011-12-03T21:48:19.893 回答
3

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

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


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

PS。这个 cstheory.se 的答案很棒

于 2011-12-04T15:38:26.697 回答
2

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

╔══════════════╦═══════════════════════╦════════════════════════╦══════════════════════════════╗
║  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)    ║                              ║
║              ║                       ║                        ║                              ║
║              ║                       ║                        ║                              ║
║              ║                       ║                        ║                              ║
║              ║                       ║                        ║                              ║             
╚══════════════╩═══════════════════════╩════════════════════════╩══════════════════════════════╝

我从普林斯顿讲座幻灯片中得到了这张图片

二进制堆: 在此处输入图像描述


二项式堆:

k 棵二叉树


斐波那契堆:

在此处输入图像描述

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

  • 二项式堆:每次插入后急切地合并树。
  • 斐波那契堆:延迟合并直到下一个删除分钟。
于 2018-01-02T17:51:31.363 回答
1

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

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

于 2012-08-17T09:15:50.307 回答