Algorithm 合并两个最大堆的算法?

Algorithm 合并两个最大堆的算法?,algorithm,data-structures,merge,heap,Algorithm,Data Structures,Merge,Heap,是否有一种有效的算法来合并存储为数组的2个最大堆?这取决于堆的类型 如果它是一个标准堆,其中每个节点最多有两个子节点,并且叶子最多位于两个不同的行上,那么对于merge,您不能得到比O(n)更好的结果 只需将这两个数组放在一起,并用它们创建一个新的堆,这需要O(n) 为了获得更好的合并性能,您可以使用另一个堆变量,如斐波那契堆,它可以按O(1)摊销合并 更新: 请注意,将第一个堆的所有元素逐个插入第二个堆会更糟糕,反之亦然,因为插入需要O(log(n))。 正如您的评论所述,您似乎不知道堆在一开

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

这取决于堆的类型

如果它是一个标准堆,其中每个节点最多有两个子节点,并且叶子最多位于两个不同的行上,那么对于merge,您不能得到比O(n)更好的结果

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

为了获得更好的合并性能,您可以使用另一个堆变量,如斐波那契堆,它可以按O(1)摊销合并

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

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


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

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


    我认为您在本例中寻找的是一个二项式堆

    二项式堆是二项式树的集合,是可合并堆族的成员。2+二项式堆上的联合(合并)的最坏运行时间为O(lg n),堆中的项目总数为n


    有关更多信息,请参阅。

    是。到目前为止,您尝试了什么?高效是什么意思?好吧,如果我只是以随机顺序将每个元素插入到新堆中,我想这将是O(nlogn)的平均值。因此,我正在寻找O(log(n)^2)将注释放在问题中,这将表明您已经考虑过这个问题,并且对解决方案感兴趣,而不是琐碎的问题。@Yaron:您可以在O(n+k)中构建新堆。只需连接数组并使用默认方法构建一个新堆。这需要使用指针来实现堆,如基于指针的常规树,这与常规做法不同。我要说的是@phoeagon,我开始阅读它,它说它需要O(k)将一个数组复制到另一个数组时的数据操作,但在文章的最后指出,如果使用指针而不是基于数组的堆,则数据操作可以在固定时间内完成,从而使您返回O(logn*logk)操作。二项式堆不存储为数组