📚 由淺至深
第 19 章 中等 約 12 分鐘

堆積排序:用急診室來排序

把陣列建成 Heap,然後不斷取頂——出來的順序就是排序好的。O(n log n) 還省記憶體。

建議先看過: 18-heap

想法很簡單

既然 Max-Heap 的頂端永遠是最大值—— 取頂 → 放到陣列最後 → 重複 n 次 → 就排好了!

而且不用額外陣列——右邊放排好的,左邊還是 heap,原地(in-place)完成。

跑一遍:[4, 10, 3, 5, 1, 15]

Step 1:建 Max-Heap

從最後非葉節點開始 sift down。 最終 heap:[15, 10, 4, 5, 1, 3](樹形:根 15、左 10、右 4…)

15104513

Step 2:反覆取頂

動作陣列狀態(左 heap,右排好)
交換 [0] 和最後一格[3, 10, 4, 5, 1, 15]
Heap size 變 5,對 [0] sift down[10, 5, 4, 3, 1, 15]
交換 [0] 和 [4][1, 5, 4, 3, 10, 15]
Sift down[5, 3, 4, 1, 10, 15]
交換 [0] 和 [3][1, 3, 4, 5, 10, 15]
Sift down[4, 3, 1, 5, 10, 15]
… 繼續 …[1, 3, 4, 5, 10, 15]
[1, 3, 4, 5, 10, 15] ✓
💡關鍵想法

每跑一輪:

  1. 把 heap 的最大值(頂端)跟「heap 的最後一個位置」交換
  2. 縮小 heap 範圍(最後那格已就位)
  3. 對新頂端 sift down

n 輪後,陣列就排好了。

Pseudocode

Algorithm HeapSort(A, n):
BuildMaxHeap(A, n) // O(n)
for i ← n-1 downto 1:
swap(A[0], A[i]) // 最大值就位
SiftDown(A, 0, i) // heap size = i

複雜度

情境Big-O
時間(所有情況)O(n log n)
空間O(1) ← in-place
穩定?

n 次取頂 × 每次 O(log n) sift down = O(n log n)。建 heap 是 O(n) 不影響整體。

跟其他 O(n log n) 排序比

Heap SortMerge SortQuick Sort
平均O(n log n)O(n log n)O(n log n)
最壞O(n log n)O(n log n)O(n²) ⚠️
空間O(1)O(n) ⚠️O(log n)
穩定
Cache 友善差(heap 跳很遠)中等
💡為什麼實務上 Quick Sort 還是比 Heap Sort 受歡迎?

Heap Sort 看起來完美——最壞 O(n log n) + O(1) 空間。

但常數倍率大:sift down 每層要比較兩個小孩、跳指標、寫回。 Quick Sort 操作對 cache 友善(連續記憶體存取),實測快 2-3 倍。

Heap Sort 的優勢場景:需要保證最壞 O(n log n) 的關鍵系統(嵌入式、即時系統)。

📝考試會這樣考

題型一:跑一遍 Heap Sort。 給陣列,列出每輪的:

  • 取頂後的 heap 狀態
  • 已排序的部分

訣竅:畫表格,左 heap、右排好,每輪一行。

題型二:為什麼最壞 O(n log n)? 答:n 次取頂,每次 sift down 最多走樹高 O(log n),所以 n × log n = O(n log n)。 最壞、平均、最好都是 O(n log n),不像 Quick Sort 會退化

題型三:為什麼不穩定? 答:sift down 過程會跨越相等元素,相對順序可能變。

題型四:跟 Merge Sort 比哪個好?

  • 要 in-place → Heap Sort
  • 要穩定 → Merge Sort
  • 要快(cache)→ Quick Sort(雖然最壞 O(n²))

這章記住

  1. 建 Max-Heap → 反覆取頂並縮小範圍
  2. 時間 O(n log n) 不退化、空間 O(1)
  3. 不穩定,cache 不友善,所以實務 Quick Sort 還是常用。
  4. 考試最愛問「列出每輪 heap 狀態」——畫圖最穩。

學習進度只存在你的瀏覽器,不會上傳。