Heap Sort
Complete Binary Tree
一株二元樹(Binary Tree)若依序由左而右、由上而下排列,且除了最後一層外其餘層數皆排滿,即為 Complete Binary Tree 。
若第一個節點編號為 1 ,則從 Complete Binary Tree 任取一節點編號 k
,該節點的父節點、左邊子節點、右邊子節點都可以用公式表示:
父節點: k / 2
後無條件捨去
左邊子節點: k * 2
右邊子節點: k * 2 + 1
如下圖:
這個特性讓該資料結構可以被放在陣列之中運算。
Heap (堆積)
Heap 是一種以 Complete Binary Tree 做為骨架的資料結構,分為兩種:
Max Heap
每個父節點的值永遠大於子節點。
公式: Value[k / 2] > Value[k]
Min Heap
每個子節點的值永遠大於父節點。
公式: Value[k / 2] < Value[k]
使用 Heap 的好處是,位於節點編號 1 的值永遠都是最小值或最大值,因此對於 Heap 來說,要得到資料的極值是很方便的事。
Heapify
在進入 Heap Sort 之前必須先知道如何將陣列資料轉為 Heap。假設一組由兩個子節點加上一個父節點所組成的小型二元樹。
Heapify 的過程是將父節點與左子節點和右子節點比較,以 Max Heap 舉例,若最大值出現在某個子節點,則把該子節點的值與父節點的值互換。
由於被更換後的子節點也可能是別人的父節點,因此必須找到該子節點為父節點的小型二元樹,重複最大值的檢查與交換,以此向下層類推,這就是 Heapify 的過程。
如下圖:
Build a Heap
要將一段長度為 N 隨機數組轉換成 Heap ,只要從 2/N (若為奇數則無條件捨去)處開始 Heapify 到第一筆資料就好。
為何是 2/N ? 上面有提到 Complete Binary Tree 的任一節點 X 的父節點位置為 2/X ,反過來說,也只有 2/N 以下的數字才會有子節點,有子節點才有做 Heap 的意義。
Heap Sort (堆積排序)
概念
Heap Sort 就是利用 Heap 資料結構的特性來對一串數列進行排序的演算法。舉例來說,若有一串數列是以 Min Heap 的方式排列,其編號為 1 的節點的值永遠是最小值。
因此只要把編號為 1 的節點的值取走,然後將剩下的數列重新排為 Heap ,編號為 1 的節點又會再次出現剩餘資料的的最小值,重複「取走、重排」動作至最後一筆資料,就可以完成排序。
整個程式分三部分:
- Build Heap:將陣列資料轉換成 Max Heap 資料結構
- Swap:把在節點 1 產生的最大值換到底部,將其視作已排序的值,不再動它
- Heapify:把剩下的數字重新轉換成 Max Heap,使新的最大值產生
流程圖
程式碼
在 heapSort
前段,我們刻意在隨機數組前插入一個任意欄位。這是因為 Heap 只有在節點編號從 1 開始算起時,父節點與子節點間才會有上述公式的關聯性。
1 | // 隨機陣列 |