void sort(int a[], int size) {
int i = 0, j = size - 1;
int pivot = a[0]; // 基準值
if (size > 1) {
while (i < j) {
// 從右向左找首個 < pivot
for (; i < j; j--) {
if (a[j] < pivot) {
a[i] = a[j]; // 填左坑
break;
}
}
// 從左向右找首個 > pivot
for (; i < j; i++) {
if (a[i] > pivot) {
a[j] = a[i]; // 填右坑
break;
}
}
}
a[i] = pivot; // 基準歸位
sort(a, i); // 遞歸左半
sort(&a[i+1], size - i - 1); // 遞歸右半
}
}
初始陣列:[6, 9, 7, 3, 4],pivot=6,i=0, j=4
| 步驟 | 動作 | 陣列狀態 | 坑位 | i/j |
|---|---|---|---|---|
| 1 | 右掃描找 4<6 | [4, 9, 7, 3, 4] | 索引 0 | i=0, j=4 |
| 2 | 左掃描找 9>6 | [4, 9, 7, 3, 4] | 索引 1 | i=1, j=4 |
| 3 | 右掃描找 3<6 | [4, 3, 7, 3, 4] | 索引 1 | i=1, j=3 |
| 4 | 左掃描找 7>6 | [4, 3, 7, 3, 4] | 索引 2 | i=2, j=3 |
| 5 | i==j=2 循環結束 | [4, 3, 6, 3, 4] | 基準歸位 | i=j=2 |
最終:[4, 3, 6, 7, 9],基準 6 歸位,左側 ≤ 6,右側 ≥ 6。
pivot = a[0],原位置成為第一個坑。i == j 時坑位即基準最終位置。size <= 1 直接返回。&a[i+1] 傳遞右半區首地址,size - i - 1 為右半長度。| 優化點 | 做法 | 效果 |
|---|---|---|
| 基準選擇 | 三數取中 / 隨機 | 避免有序陣列退化 O(n²) |
| 小區間切換 | size < 10 用插入排序 | 減少遞歸開銷 |
| 尾遞歸消除 | 迴圈處理較大分區 | 棧深度 O(log n) → O(1) |
| 三路分區 | Dijkstra 荷蘭國旗 | 大量重複鍵值加速 |