快速排序由 Tony Hoare 1960 年發明,平均時間複雜度 O(n log n),原地排序、不穩定。因內層迴圈極簡且緊湊,實際表現通常優於同階合併排序、堆排序。
原始:3 5 2 6 2 基準:3 第1輪: 從右找 <3 → 2,交換 → 2 5 2 6 3 從左找 >3 → 5,交換 → 2 3 2 6 5 從右找 <3 → 2,交換 → 2 2 3 6 5 指標相遇,分區完成,基準 3 歸位 遞迴左半部 [2 2]、右半部 [6 5] 最終:2 2 3 5 6
public class QuickSort {
private static int round = 0;
public static void sort(int[] arr) {
quickSort(arr, 0, arr.length - 1);
}
private static void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pivotIdx = partition(arr, low, high);
quickSort(arr, low, pivotIdx - 1);
quickSort(arr, pivotIdx + 1, high);
}
}
private static int partition(int[] arr, int low, int high) {
int pivot = arr[low];
round++;
System.out.printf("第 %d 輪分區 [%d-%d] 基準=%d%n", round, low, high, pivot);
while (low < high) {
while (low < high && arr[high] >= pivot) {
System.out.printf(" 右→左 找<%d high=%d%n", pivot, high);
high--;
}
swap(arr, low, high);
while (low < high && arr[low] <= pivot) {
System.out.printf(" 左→右 找>%d low=%d%n", pivot, low);
low++;
}
swap(arr, low, high);
}
return low;
}
private static void swap(int[] arr, int i, int j) {
if (i != j) {
int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
System.out.print(" 交換後: ");
Arrays.stream(arr).forEach(x -> System.out.print(x + " "));
System.out.println();
}
}
public static void main(String[] args) {
int[] data = {3, 5, 2, 6, 2};
System.out.println("原始: " + Arrays.toString(data));
sort(data);
System.out.println("結果: " + Arrays.toString(data));
}
}
| 場景 | 時間複雜度 | 空間複雜度 |
|---|---|---|
| 平均 | O(n log n) | O(log n) 遞迴棧 |
| 最差(已有序) | O(n²) | O(n) |
| 最佳 | O(n log n) | O(log n) |
O(log n)。快速排序以優雅的分治思想、極少的額外空間、優異的快取局部性,成為工業界排序首選(如 JDK Arrays.sort() 基本類型使用雙軸快排)。理解其分區邏輯與優化方向,是演算法面試與高效能工程的必修課。