快速排序天然適合遞迴:
`QuickSort(arr, low, high)` → 分區 → 遞迴排序左半部 → 遞迴排序右半部
#include
#include
/**
* 交換兩個整數
*/
void swap(int *a, int *b) {
int t = *a; *a = *b; *b = t;
}
/**
* Hoare 分區:返回分區點索引
* 陣列區間 [low, high] (含兩端)
*/
int partition(int arr[], int low, int high) {
int pivot = arr[low]; // 選第一個元素為基準 (教學簡化,實務建議三數取中)
int i = low - 1;
int j = high + 1;
while (1) { // 分區掃描通常用迴圈,純遞迴極繁複且無意義
do { i++; } while (arr[i] < pivot);
do { j--; } while (arr[j] > pivot);
if (i >= j) return j;
swap(&arr[i], &arr[j]);
}
}
/**
* 快速排序遞迴主函數
* @param arr 待排序陣列
* @param low 區間起始索引 (含)
* @param high 區間結束索引 (含)
*/
void quickSort(int arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high); // 分區
quickSort(arr, low, pi); // 遞迴排序左半部
quickSort(arr, pi + 1, high); // 遞迴排序右半部
}
}
/* 輔助:列印陣列 */
void printArray(int arr[], int n) {
for (int i = 0; i < n; i++) printf("%d ", arr[i]);
printf("\n");
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90, 5, 77, 3};
int n = sizeof(arr) / sizeof(arr[0]);
printf("原始陣列: ");
printArray(arr, n);
quickSort(arr, 0, n - 1);
printf("排序後: ");
printArray(arr, n);
return 0;
}
QuickSort(0, 9) pivot=64 → partition → pi=6
├─ QuickSort(0, 6) pivot=12 → pi=2
│ ├─ QuickSort(0, 2) pivot=5 → pi=1
│ │ ├─ QuickSort(0, 1) → sorted
│ │ └─ QuickSort(2, 2) → base case
│ └─ QuickSort(3, 6) pivot=22 → pi=4
│ ├─ QuickSort(3, 4) → sorted
│ └─ QuickSort(5, 6) → sorted
└─ QuickSort(7, 9) pivot=77 → pi=8
├─ QuickSort(7, 8) → sorted
└─ QuickSort(9, 9) → base case
// 純遞迴掃描 i, j (教學展示遞迴可替代迴圈,實務不可用)
int partitionRecursive(int arr[], int low, int high, int pivot, int i, int j) {
if (i >= j) return j;
if (arr[i] < pivot) return partitionRecursive(arr, low, high, pivot, i+1, j);
if (arr[j] > pivot) return partitionRecursive(arr, low, high, pivot, i, j-1);
swap(&arr[i], &arr[j]);
return partitionRecursive(arr, low, high, pivot, i+1, j-1);
}
| 演算法 | 遞迴結構 | 時間複雜度 | 空間複雜度 | 穩定 |
|---|---|---|---|---|
| 合併排序 | 分半遞迴排序 → 合併 | O(n log n) 穩定 | O(n) 輔助陣列 | 是 |
| 堆積排序 | 建堆 (迴圈) + 下沉 (遞迴/迴圈) | O(n log n) | O(1) 或 O(log n) | 否 |
| 插入排序 | 遞迴排序前 n-1 → 插入第 n 個 | O(n²) | O(n) 堆疊 | 是 |