# 2.5 - 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:

&#x20;$$\sum\_{i=1}^{N} log(i) = log(n!)\simeq O(nlogn)$$&#x20;

#### 2.4 Build a Heap(Bottom-Up)

1. 先將資料以Complete Binary Tree呈現
2. 從最後一個父點開始調整成Heap，直到Root

Time:

假設height= $$K$$ ，節點總數= $$n$$ ，某一節點位於第i階(level)

則調整節點最大成本為 $$K-i$$ ，level i最多有 $$2^{i-1}$$ 個節點

總成本:  $$\sum\_{i=1}^{K}(k-i)2^{i-1} = \sum\_{i=1}^{K-1}(k-i)2^{i-1}=S$$&#x20;

$$S = (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=\frac{2^k-2^1}{2-1}-(k-1)\\\quad=2^k-k-1\quad(k=log\_{2}(n+1))$$

&#x20;$$S=(n+1)-log\_{n}(n+1)-1$$&#x20;

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
