构建堆时间复杂度最坏情况vs上限/紧上限

时间:2015-01-11 14:46:25

标签: java algorithm heap time-complexity

HERE据说构建堆的最坏情况时间复杂度是O(nlogn),但上限是O(n)。

上限与最坏情况下的时间复杂度有何不同,以及何时对其他人更有意义。 是紧张的上限任何不同?

1 个答案:

答案 0 :(得分:2)

构建堆(也称为 Heapify 总是 O(n),无论输入分布或堆的分支因子如何(二进制,三元堆< / EM> ...)。

你误读了提供的链接,它说:(重点是我的)

  

虽然最坏情况复杂度看起来像 O(nLogn),但时间复杂度的上限是O(n)。

基本上,heapify如何工作? (为了清楚起见,我假设我们使用的是二进制堆)

首先让我们回想一下二进制堆的堆条件(使用数组A):

  

对于任何i∈[0,[N / 2],A [i]≤A[2i + 1] AND A [i]≤A[2i + 2]

注意:您通常会找到从索引1开始的数组所表示的相同条件。在这种情况下,您只需要&#34;删除&#34; 1,即。 2i + 1变为2i,2i + 2变为2i + 1.

为什么这个条件仅限于堆的前半部分?简单,对于任何i&gt; N / 2,2i + 1和2i + 2都不是有效索引。

<强> HEAPIFY
输入: N个元素的数组
输出:强制执行堆条件的相同N个元素的数组

void sink(int [] A, int i, int n) {
    int highest = 2*i+1;
    if (2*i+1 >= n)
        return;
    if (2*i+2 < n && A[2*i+2] > A[highest])
        ++highest;
    if (A[i] < A[highest]) {
        swap(A, i, highest);
        sink(A, highest, n);
    }
}

void heapify(int [] A, int n) {
    for (int i = n/2; i >= 0; --i) {
        sink(A, i, n);
    }
}

假设我们有一个完整的二进制堆,这样的堆恰好包含N = 2 h + 1 - 给定整数的1个元素h> = 0。堆作为树。索引0是树的根(高度1),索引1,2是此根的子节点(高度0),依此类推。树的高度是整数h。

算法从高度h-1开始。高度为h-1的2 h-1 元素在向下沉降时最多可移动一次。然后,高度为h-2的2 h-2 元素每个元素最多可以触发2个交换...根(高度0的2 0 元素)可以触发最多是互换。最后,构建堆的最大交换次数是:

  

MaxSwap = sum(k=0..h-1, 2k.(h-k)) = 2 h + 1 - h - 2≤2 h + 1 - 1 = N

构建堆的最大比较次数是最大交换次数的两倍。 对于任何&#34;不完整的&#34;堆,即。 2 h ≤N<1。 2 h + 1 - 1,推理仍然有效。

结论:Heapify O(N),其中N是堆的大小。


加成

从输入数组构建Maxheap的正在运行的Java示例:here