Heapify


Question

Given an integer array, heapify it into a min-heap array.

For a heap array A, A[0] is the root of heap, and for each A[i], A[i 2 + 1] is the left child of A[i] and A[i 2 + 2] is the right child of A[i].

Solution

我記得這題第一次寫沒有寫出來。第二次寫寫出了 siftdown,但寫 siftup 還是寫不出。

主要原因是在寫 siftup 的過程中,我讓 for loop 從尾巴走回來,不正確的原因在於,siftup 要一直去跟自己的 parent 比較,在每個 iteration 中,要確認的是所有在當前的 index 之前的 node 都已經變成 min heap 了,所以必須從上面走下來。

所以,如果是寫 siftdown,for loop 可以從 A.length / 2 往回走。為什麼呢?因為 siftdown 要確保的是,從當前這個 index 往下的所有 node 都是 min heap,而在 heap 中,會有一半的 node 是 leaf,因此可以從中間往回走

siftup

    public void heapify(int[] A) {
        for (int i = 0; i < A.length; i++) {
            siftup(A, i);
        }
    }

    public void siftup(int[] A, int childIndex) {
        while (childIndex > 0) {
            int parentIndex = (childIndex - 1) / 2;
            if (A[parentIndex] < A[childIndex]) {
                break;
            }

            int temp = A[parentIndex];
            A[parentIndex] = A[childIndex];
            A[childIndex] = temp;

            childIndex = parentIndex;
        }
    }

siftdown

    public void heapify(int[] A) {
        // write your code here

        for (int i = A.length/2; i >= 0; i--) {
            siftdown(A, i);
        }
    }

    public void siftdown(int[] A, int k) {
        while (k < A.length) {
            int leftIndex = (2*k + 1 < A.length)? 2*k + 1: -1;
            int rightIndex = (2*k + 2 < A.length)? 2*k + 2: -1;

            int left = (leftIndex != -1)? A[leftIndex] : Integer.MAX_VALUE;
            int right = (rightIndex != -1)? A[rightIndex] : Integer.MAX_VALUE;
            if (right >= A[k] && left >= A[k]) {
                break;
            }

            int changeIndex = (left >= right) ? rightIndex : leftIndex;
            int temp = A[k];
            A[k] = A[changeIndex];
            A[changeIndex] = temp;

            k = changeIndex;
        }
    }

results matching ""

    No results matching ""