歸併排序採用分治法:
public class MergeSort {
private static int[] aux; // 輔助數組,避免重複分配
public static void sort(int[] arr) {
aux = new int[arr.length];
sort(arr, 0, arr.length - 1);
}
private static void sort(int[] arr, int lo, int hi) {
if (lo >= hi) return;
int mid = lo + ((hi - lo) >>> 1);
sort(arr, lo, mid);
sort(arr, mid + 1, hi);
merge(arr, lo, mid, hi);
}
// 合併 [lo..mid] 和 [mid+1..hi]
private static void merge(int[] arr, int lo, int mid, int hi) {
// 複製到輔助數組
System.arraycopy(arr, lo, aux, lo, hi - lo + 1);
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++) {
if (i > mid) arr[k] = aux[j++];
else if (j > hi) arr[k] = aux[i++];
else if (aux[j] < aux[i]) arr[k] = aux[j++]; // < 保證穩定性
else arr[k] = aux[i++];
}
}
}
public static void sortBU(int[] arr) {
int n = arr.length;
int[] aux = new int[n];
for (int sz = 1; sz < n; sz <<= 1) { // 子數組大小:1,2,4,8...
for (int lo = 0; lo < n - sz; lo += sz << 1) {
int mid = lo + sz - 1;
int hi = Math.min(lo + (sz << 1) - 1, n - 1);
merge(arr, aux, lo, mid, hi);
}
}
}
// 合併輔助方法(複用 aux)
private static void merge(int[] arr, int[] aux, int lo, int mid, int hi) {
System.arraycopy(arr, lo, aux, lo, hi - lo + 1);
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++) {
if (i > mid) arr[k] = aux[j++];
else if (j > hi) arr[k] = aux[i++];
else if (aux[j] < aux[i]) arr[k] = aux[j++];
else arr[k] = aux[i++];
}
}
Arrays.sort 對象數組即採用此策略)。arr[mid] <= arr[mid+1] 則跳過合併。arr 與 aux 角色,省去複製回原數組步驟。Arrays.parallelSort() 利用 ForkJoinPool 並行排序子數組再合併。LinkedList.sort())。歸併排序是唯一兼具 O(n log n) 最壞時間、穩定性、順序訪問特性的通用排序算法。雖需 O(n) 空間,但在對象排序、外部排序、並行計算等領域不可替代。Java 標準庫對象數組排序(TimSort)即基於歸併與插入排序混合優化而成。