2.5 - Heap

介紹heap、運作及其應用

1. 定義

  1. 可以分為max-heap與min-heap(以max-heap為例)

  2. 本身是complete binary tree(適合用array存放)

  3. 所有節點的parent值都大於其children

  4. root具有最大值

      40
     /  \
    20   10
   /  \
  5    9

2. 運作

2.1 Insert x in heap

  1. 將x存放於最後一個節點的下一個位置

  2. 往上和父點比較,若父點叫小則交換,直到root。

2.2 Delete max in heap

  1. 取出root的最大值

  2. 將最後一個節點刪除,並放到root中

  3. 從root往下調整,直到root為最大值

2.3 Build a Heap(Top-Down)

從上到下使用insert()來建立Heap。

Time:

i=1Nlog(i)=log(n!)O(nlogn)\sum_{i=1}^{N} log(i) = log(n!)\simeq O(nlogn)

2.4 Build a Heap(Bottom-Up)

  1. 先將資料以Complete Binary Tree呈現

  2. 從最後一個父點開始調整成Heap,直到Root

Time:

假設height= KK ,節點總數= nn ,某一節點位於第i階(level)

則調整節點最大成本為 KiK-i ,level i最多有 2i12^{i-1} 個節點

總成本: i=1K(ki)2i1=i=1K1(ki)2i1=S\sum_{i=1}^{K}(k-i)2^{i-1} = \sum_{i=1}^{K-1}(k-i)2^{i-1}=S

S=(k1)20+(k2)21+...+2k22S=(k1)21+....+22k2+2k12SS=(k1)20+21+22+23+...+2k1S = (k-1)2^0+(k-2)2^1+...+2^{k-2}\\2S = \quad\quad\quad\quad+(k-1)2^1+....+2*2^{k-2}+2^{k-1}\\2S-S=-(k-1)2^0+2^1+2^2+2^3+...+2^{k-1} S=2k2121(k1)=2kk1(k=log2(n+1))\\S=\frac{2^k-2^1}{2-1}-(k-1)\\\quad=2^k-k-1\quad(k=log_{2}(n+1))

S=(n+1)logn(n+1)1S=(n+1)-log_{n}(n+1)-1

Time = O(n)

void AdjustBottomUp(char *heap, int i, int n){
    int j = 2*i+1;     //左子點
    while(j <= n){
        if (j < n)
            if (heap[j] < heap[j+1])
                Swap(&heap[j], &heap[j+1]); 左右子點交換
        if (heap[i] > heap[j]) 
            break;
        else{
            Swap(&heap[j/2], &heap[j]); //父點與子點交換
            j=j*2+1; 
            i=(j-1)/2;
        }
    }
}

void BuildHeap(char *heap){
    int n = strlen(heap);
    for (int i = n/2-1; i>=0; i--){ //i從最後一個父點開始
        AdjustBottomUp(heap, i, n-1);
    }    
}

void Swap(char *a, char *b){
    char temp = *a;
    *a = *b;
    *b = temp;
}

3. 應用

  1. 製作priority queue的最佳資料結構,因為insert(),delete_max()皆只需O(logn)。

  2. Heap Sort

Last updated