Heapify

給一個數組,將它化為 Heap 的結構,也就是兒子都比父親小(大)

有兩種做法,一種是從頭開始掃,一個一個往下交換,複雜度是 O(n log n)

因為掃 n 個,共有 O(log n) 層

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

//每次都往 father 比較
public void shiftup(int[] A, int k) {
    while (k != 0) {
        int father = (k-1)/2;
        if (A[father] < A[k]) {
            break;
        }
        int temp = A[father];
        A[father] = A[k];
        A[k] = temp;
        k = father;
    }
}

另一種是從 n/2 開始,往下交換,因為 n/2 是倒數第二層,所以時間複雜度會是

(n/2 * 1) + (n/4 * 2) + .... (1 * log n) => O(n)

為什麼 n/2 是倒數第二層? 可以這樣想:

n/2 * 2 = n 表示 n/2 這層的下一層就會讓整棵樹加起來是 n 個,那不就是倒數第二層嗎?

public void heapify(int[] A) {
    for (int i = A.length/2; i>=0; i--) {
        siftdown(A, i);
    }
}

public void shiftdown(int[] A, int k) {
    // 條件不可以是 (k*2+1 < A.length && k*2+2 < A.legth) 這樣後面的數字會判斷不到
    while (k < A.length) {
        int smallest = k;
        if (k*2+1 < A.length && A[k*2+1] < A[smallest]) {
            smallest = k*2+1;
        }
        if (k*2+2 < A.legth && A[k*2+2] < A[smallest]) {
            smallest = k*2+2;
        }
        if (smallest == k)
            break;
        int temp = A[k];
        A[smallest] = A[k];
        A[k] = temp;
        k = smallest;
    }
}

results matching ""

    No results matching ""