快速排序採用分治法:
以數組 [21, 8, 2, 18, 0, 9, 27, 12, 5, 24] 為例,取首元素 21 為基準:
left=0(基準位置),right=9(末尾)right 索引)left 和 right 位置元素,基準隨之移動到 rightleft 索引)left 和 right 位置元素,基準移動到 leftleft == right,分區完成,基準歸位原數組: 21、8、2、18、0、9、27、12、5、24 第0次: 5、8、2、18、0、9、27、12、21、24 (基準21歸位) 第1次: 5、8、2、18、0、9、21、12、27、24 (右半區基準27歸位) 第2次: 5、8、2、18、0、9、12、21、27、24 (右半區基準12歸位) 第3次: 0、8、2、18、5、9、12、21、27、24 (左半區基準5歸位) 第4次: 0、5、2、18、8、9、12、21、27、24 (左半區基準8歸位) 第5次: 0、2、5、18、8、9、12、21、27、24 (左半區基準2歸位) 第6次: 0、2、5、12、8、9、18、21、27、24 (左半區基準18歸位) 第7次: 0、2、5、9、8、12、18、21、27、24 (左半區基準9歸位) 第8次: 0、2、5、8、9、12、18、21、27、24 (左半區基準8歸位) 第9次: 0、2、5、8、9、12、18、21、24、27 (右半區基準24歸位)
public class QuickSort {
private int time = 0; // 用於演示打印輪次
/** 入口方法 */
public void callQuickSort(int[] array) {
printArray("原數組:", array);
quickSort(array, 0, array.length - 1);
}
/** 遞歸排序主邏輯 */
public void quickSort(int[] array, int left, int right) {
if (left >= right) return; // 遞歸終止條件
int index = qSort(array, left, right); // 分區,返回基準最終位置
quickSort(array, left, index); // 排序左半區
quickSort(array, index + 1, right); // 排序右半區
}
/** 單次分區核心邏輯 */
private int qSort(int[] array, int left, int right) {
int mid = left; // 基準索引,初始為左端
int temp;
while (left < right) {
if (mid != right) { // 基準在左側,從右向左掃描
if (array[mid] > array[right]) {
// 找到小於基準的元素,交換
temp = array[right];
array[right] = array[mid];
array[mid] = temp;
mid = right; // 基準移動到 right 位置
printArray("第" + time++ + "次循環排序結果: ", array);
} else {
right--; // 繼續向左掃描
}
} else { // 基準在右側,從左向右掃描
if (array[left] > array[mid]) {
// 找到大於基準的元素,交換
temp = array[left];
array[left] = array[mid];
array[mid] = temp;
mid = left; // 基準移動到 left 位置
printArray("第" + time++ + "次循環排序結果: ", array);
} else {
left++; // 繼續向右掃描
}
}
}
return mid; // 返回基準最終位置
}
private void printArray(String prefix, int[] array) {
System.out.print(prefix);
for (int n : array) System.out.print(n + "、");
System.out.println();
}
public static void main(String[] args) {
int[] a = {21, 8, 2, 18, 0, 9, 27, 12, 5, 24};
new QuickSort().callQuickSort(a);
}
}
| 指標 | 複雜度 | 說明 |
|---|---|---|
| 時間複雜度(平均) | O(n log n) | 每層分區 O(n),遞歸深度 log n |
| 時間複雜度(最壞) | O(n²) | 已有序數組,每次分區極不平衡 |
| 時間複雜度(最好) | O(n log n) | 每次分區均勻 |
| 空間複雜度 | O(log n) | 遞歸棧深度,原地排序無額外數組 |
| 穩定性 | 不穩定 | 相等元素相對位置可能改變 |
不熟練遞歸的同學建議先閱讀:遞歸核心原理圖解
核心思想:大問題分解為同結構的小問題,直到基線條件終止。