合并相同大小的堆

时间:2013-02-21 23:43:41

标签: algorithm data-structures heap

有人可以解释为什么合并堆的以下算法不正确吗?

假设我们有两个(最大)堆H1和H2。

合并它们:

创建一个人工虚拟节点,其键值为负无穷大,并将其放在根上,H1和H2作为子节点附加。然后做一个O(log n)气泡向下步骤,最终将根交换到叶子位置,最终删除它。生成的结构是一个合并的堆。

我已经看到维基百科和其他地方合并两个相同大小的堆的声明是Theta(n)操作,与我上面所写的相反。

2 个答案:

答案 0 :(得分:3)

至少在堆通常被实现的情况下(节点的位置隐含了链接),你似乎几乎忽略了一个部分(“H1和H2作为子节点附加”)本身具有线性复杂性。

由于堆通常是实现的,因此您有一个线性集合(例如,数组),其中每个元素N具有元素2N和2N + 1作为其子元素(例如,具有基于1的数组,元素1的子元素是元素2和3,元素2的子元素是4和5)。因此,在我们到达合并操作的起始点之前,您需要交错两个堆中的元素。

如果你从明确链接的二进制树开始(只是遵循堆式规则,而不是例如二进制搜索树排序)那么你是对的,合并可以用对数复杂度完成 - 但我怀疑原始文章打算引用那种结构。

答案 1 :(得分:2)

如果您将其作为树实施,那么您的解决方案是正确的。但正如Jerry所说,合并基于数组的堆不能在亚线性时间内完成。

根据合并的频率和大小,我建议您使用虚拟堆。您可以将其实现为堆堆(使用数组)。在几次合并之后,您可以懒惰地将多个内部堆合并到一个大堆中。

相关问题