给定一个数组,是否有O(n)算法来构建最大堆?
答案 0 :(得分:22)
是的,就像在这段代码中一样:
for (int i = N/2; i >= 0; --i)
push_heap(heap + i, N - i);
(push_heap
是一个函数,它接受指向堆和堆大小的指针并推送堆顶部,直到遵守堆条件或节点到达堆的底部。)
要了解这是O(N)的原因,请查看完整的二叉树:
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)。
答案 1 :(得分:5)
是的,有:Building a heap。
答案 2 :(得分:0)
提示:假设您使用的是任意二叉树而不是数组。您能想到一种有效的方法来修复任何不满足堆属性的节点吗?
答案 3 :(得分:-1)
如果您使用Fibonacci Heap,则会获得amortized O(1)插入。因此,您可以从数组中以摊销的O(n)构建最大堆。
执行此类,我将其作为练习*。
*虽然,维基百科页面上有链接的示例实现。
答案 4 :(得分:-4)
我不这么认为。我认为你能做的最好的事情就是O(log n),或者用像fib堆这样的东西做得更好。