build heap time complexity worst case vs upper bou

2019-09-02 02:19发布

HERE it is said that the worst case time complexity of building a heap is O(nlogn) but upper bound is O(n).

How is a upper bound different from worst case time complexity and when one makes more sense over other. And is tight upper bound any different ?

1条回答
手持菜刀,她持情操
2楼-- · 2019-09-02 02:58

Building a heap (also called Heapify) is always O(n), regardless of the input distribution or the branching factor of the heap (binary, ternary heaps...).

You misread the provided link, it states: (emphasis is mine)

Although the worst case complexity looks like O(nLogn), upper bound of time complexity is O(n).

Basically, how does heapify work? (For clarity's sake I'll assume we are using binary heaps)

First let's recall what is the heap condition for a binary heap (using an array A):

For any i ∈ [0, [N/2], A[i] ≤ A[2i+1] AND A[i] ≤ A[2i+2]

Note: You will usually find the same condition expressed for an array starting at index 1. In that case you just have to "remove" 1, ie. 2i+1 becomes 2i and 2i+2 becomes 2i+1.

Why is this condition limited to the first half of the heap? Simple, for any i > N/2, neither 2i+1 nor 2i+2 are valid indexes.

HEAPIFY
Input: An array of N elements
Output: An array of the same N elements that enforces the heap condition

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);
    }
}

Suppose we have a complete binary heap, such a heap contains exactly N = 2h+1 - 1 elements for a given integer h >= 0. View the heap as a tree. Index 0 is the root of the tree (height 1), indexes 1,2 are the children of this root (height 0), and so on. The height of the tree is the integer h.

The algorithm starts at height h-1. The 2h-1 elements at height h-1 can be moved at most once while sinking them down. Then, the 2h-2 elements at height h-2 can trigger at most 2 swaps per element... The root (20 element of height 0) can trigger at most h swaps. In the end, the maximum number of swaps to build the heap is :

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

The maximum number of comparisons to build the heap is twice the maximum number of swaps. For any "incomplete" heap, ie. 2h ≤ N < 2h+1 - 1, the reasoning still holds.

Conclusion: Heapify is O(N) where N is the size of the heap.


Bonus

A running Java example that builds a Maxheap from an input array : here

查看更多
登录 后发表回答