步步看懂

Merge Sort

合併排序

用互動動畫一步步看懂合併排序(Merge Sort):遞迴樹顯示每一層的拆分與合併,搭配合併過程與呼叫堆疊,並可輸入自己的資料。

0123382743398210左半右半合併
比較次數
0
寫入次數
0
最大遞迴深度
0

合併排序在做什麼

合併排序是「分而治之」:把大問題切成小問題,解決後再合起來。

  1. 拆分:把區間從中間切成左右兩半,各自遞迴處理,直到只剩一個數字。只有一個數字的區間一定是已排序的。
  2. 合併:兩個已排序的半邊要合成一個。每次比較兩邊最前面的數字,把較小的先放進結果,重複到其中一邊用完,再把另一邊剩下的接在後面。
  3. 回到上一層,繼續合併,直到整個陣列合併完成。

怎麼讀這張圖

  • 上方的遞迴樹:每一層是一列,欄位對齊原陣列的索引。虛線框是已經切開的區間,淡藍底是已經排好的區間,粗框是目前正在處理的那一段。
  • 下方的合併區:左半、右半與合併結果三列。已被取走的數字會劃線,剛取走的那個是實心;兩邊目前最前面的數字以粗框標出,也就是這一步正在比較的對象。
  • 右側的呼叫堆疊:還沒有返回的遞迴呼叫,最上面是目前這一層。堆疊最深只有 ⌈log₂ n⌉ + 1,不會隨著資料量快速變大。

為什麼是 O(n log n)

7 個數字切成一半一半,只要 3 層就會切到單一數字,所以層數是 log n。每一層的合併,所有數字各被比較並寫入至多一次,合起來是 n。層數乘上每層的工作量,就是 n log n。

試著按「已排序」或「隨機」比較看看:比較次數會有些差異,但寫入次數幾乎一樣,因為每個數字在每一層都要被寫入一次。

複雜度

最佳O(n log n)
平均O(n log n)
最差O(n log n)
額外空間O(n)
穩定是

常見問題

合併排序為什麼不管資料長怎樣都是 O(n log n)?
因為它每次都固定從中間切成兩半,一共切 log n 層;而每一層合併時,所有數字各被處理一次,合起來是 n。資料已排好或完全反序,步驟數幾乎一樣。
合併排序需要多少額外空間?
合併時要暫存左右兩半,所以是 O(n)。這是它和快速排序最大的取捨:換來穩定與固定的 O(n log n),付出額外記憶體。
合併排序是穩定的嗎?
是。兩邊比到相等的數字時一律先取左邊,相等元素的相對順序不會改變。
什麼時候適合用合併排序?
需要穩定排序、要保證最差情況也是 O(n log n),或資料放在不適合隨機存取的地方(例如鏈結串列、磁碟上的大檔案)時。