合并两个最大堆的算法?

时间:2009-10-20 15:10:19

标签: algorithm data-structures merge heap

是否有一种有效的算法可以合并存储为数组的2个最大堆?

3 个答案:

答案 0 :(得分:16)

这取决于堆的类型。

如果它是一个标准堆,其中每个节点最多有两个子节点并且填满了叶子最多有两个不同的行,那么合并就不能比O(n)好。

只需将两个数组放在一起,然后用它们创建一个新的堆,它需要O(n)。

为了获得更好的合并性能,您可以使用另一个堆变体,如Fibonacci-Heap,它可以合并为O(1)摊销。

<强>更新 请注意,将第一个堆的所有元素逐个插入第二个堆,反之亦然,因为插入需要O(log(n))。 正如您的评论所述,您似乎不知道堆在开始时是如何以最佳方式构建的(对于标准二进制堆也是如此)

  1. 创建一个数组并以任意顺序放入两个堆的元素
  2. 现在从最低级别开始。最低级别包含大小为1的琐碎最大堆,因此该级别已完成
  3. 向上移动一级。当其中一个“子堆”的堆状态被违反时,将“子堆”的根与其较大的子进行交换。之后,第2级完成
  4. 移至第3级。当违反堆条件时,像以前一样处理。用它更大的孩子交换它并递归处理直到所有匹配到3级
  5. ...
  6. 当您到达顶部时,您在O(n)中创建了一个新堆。
  7. 我在这里省略了一个证明,但你可以解释这个,因为你已经完成了底层的大部分堆,你不需要交换很多内容来重新建立堆条件。你已经操作了更小的“子堆”,这比你将每个元素插入其中一个堆中的要好得多=&gt;然后,你将每次在整个堆上操作,每次都需要O(n)。

    更新2:二项式堆允许在O(log(n))中合并,并且符合您的O(log(n)^ 2)要求。

答案 1 :(得分:8)

大小为n和k的两个二进制堆可以在O(log n * log k)比较中合并。参见

Jörg-R. Sack and Thomas Strothotte, An algorithm for merging heaps, Acta Informatica 22 (1985), 172-186.

答案 2 :(得分:1)

我认为在这种情况下你要找的是二项式堆。

二项式堆是二叉树的集合,是可合并堆系列的成员。对于2个二项式堆上的并集(合并)的最坏情况运行时间是堆中的n个项目是O(lg n)。

有关详细信息,请参阅http://en.wikipedia.org/wiki/Binomial_heap