堆排序利用二叉堆(完全二叉樹)特性:大根堆中父節點 ≥ 子節點,堆頂為最大元素。算法分兩階段:
heapify)。heapify(下沉調整),直到堆大小為 1。public class HeapSort {
public static void sort(int[] arr) {
int n = arr.length;
// 1. 建堆:從最後一個非葉子節點開始下沉
for (int i = (n >>> 1) - 1; i >= 0; i--) {
heapify(arr, n, i);
}
// 2. 排序:逐個提取堆頂
for (int end = n - 1; end > 0; end--) {
swap(arr, 0, end); // 最大值移至末尾
heapify(arr, end, 0); // 對剩餘堆下沉調整
}
}
// 下沉調整:將索引 i 節點下沉到合適位置,堆大小為 size
private static void heapify(int[] arr, int size, int i) {
int largest = i;
int left = (i << 1) + 1;
int right = (i << 1) + 2;
if (left < size && arr[left] > arr[largest]) largest = left;
if (right < size && arr[right] > arr[largest]) largest = right;
if (largest != i) {
swap(arr, i, largest);
heapify(arr, size, largest); // 遞歸下沉
}
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
2*i+1,右 2*i+2,父 (i-1)>>>1,無需哨兵位,緩存友好。| 算法 | 平均時間 | 最壞時間 | 空間 | 穩定 | 備註 |
|---|---|---|---|---|---|
| 堆排序 | O(n log n) | O(n log n) | O(1) | 否 | 最壞情況有保障,適合實時系統 |
| 快速排序 | O(n log n) | O(n²) | O(log n) | 否 | 常數因子小,實際最快,但最壞需隨機化避免 |
| 歸併排序 | O(n log n) | O(n log n) | O(n) | 是 | 穩定,適合鏈表/外部排序 |
Java Arrays.sort() 基本類型用雙軸快速排序,對象用 TimSort。堆排序常用於:
PriorityQueue 即基於堆)。