是否有 O(n) 算法来构建最大堆?

Is there a O(n) algorithm to build a max-heap?

提问人:MainID 提问时间:11/24/2009 最后编辑:Cory PetoskyMainID 更新时间:11/25/2009 访问量:12911

问:

给定一个数字数组,是否有 O(n) 算法来构建最大堆?

算法

评论

2赞 FrustratedWithFormsDesigner 11/24/2009
也许如果你的输入已经正确排序。
0赞 MainID 11/24/2009
@Frustrated...:没有订购。

答:

-4赞 Jeff Ober 11/24/2009 #1

我不这么认为。我认为你能做的最好的事情是 O(log n) 或更好一点,比如 fib 堆。

评论

3赞 jason 11/24/2009
O(log n)是(即,如果是,那么如果)。O(n)fO(log n)fO(n)
0赞 PeterAllenWebb 11/25/2009
我想他一定是指 O(n log n)?
0赞 jason 11/25/2009
我不清楚。我认为斐波那契堆中的插入是摊销的,因此建筑物是摊销的。O(1)O(n)
0赞 Has QUIT--Anony-Mousse 12/25/2011
自下而上构建二进制堆是 。O(n)
-1赞 Kevin Montrose 11/24/2009 #2

如果您使用斐波那契堆,则会得到摊销的 O(1) 插入。因此,您可以从数组中构建一个摊销 O(n) 的最大堆。

这样的实施,我离开作为一个练习*。

*不过,维基百科页面上有链接的示例实现。

5赞 Rafał Dowgird 11/24/2009 #3

是的,有:构建堆

评论

0赞 Anna 11/25/2009
+1.更多的是答案的语气,而不是答案本身:)
1赞 PeterAllenWebb 11/25/2009
您自己的链接表明这是不可能的。它应该说不,没有......
0赞 Rafał Dowgird 11/25/2009
@Peter:引用链接:“因此,堆砌所有子树的成本是:[snip 方程] O(n)”
24赞 Alexandru 11/25/2009 #4

是的,就像以下代码一样:

for (int i = N/2; i >= 0; --i)
    push_heap(heap + i, N - i);

(push_heap是一个函数,它接受指向堆和堆大小的指针,并推送堆的顶部,直到遵循堆条件或节点到达堆的底部。

要了解为什么这是 O(N),请查看完整的二叉树:

  • 1/2 个元素(最后一级,i > N/2)最多以 0 步向下推 -> N/2 * 0 次操作
  • 1/4 个元素(最后 1 级,i > N/4)最多下推 1 步 -> N/4 * 1 次操作
  • 1/8 个元素(最后 2 级,i > N/8)最多下推 2 步 -> N/8 * 2 次操作 ...

      N/4 * 1 + N/8 * 2 + N/16 * 3 + ... =
    
      N/4 * 1 + N/8 * 1 + N/16 * 1 + ... +
                N/8 * 1 + N/16 * 2 + ... =
    
      N/4 * 1 + N/8 * 1 + N/16 * 1 + ... +    // < N/2
                N/8 * 1 + N/16 * 1 + ... +    // < N/4
                          N/16 * 1 + ... +    // < N/8
                                     ... =    // N/2 + N/4 + N/8 + ... < N
    

希望数学不是真的太复杂。如果你看一下树,加上每个节点可以向下推的程度,你会看到上限 O(N)。

评论

0赞 khelll 10/5/2014
伙计,你让数学比 WIKI 文章简单得多!非常感谢!
0赞 Krishna Kumar 6/4/2015
这个输入是什么:1、2、3、4、5、6、7、8、9。 我认为它应该是 O(nlogn)?