冒泡排序 通過重複遍歷待排序數列,比較相鄰元素並交換順序錯誤的對,使較大(或較小)的元素像氣泡一樣逐步「浮」到數列末端。經過 n-1 輪遍歷後,數列有序。
void bubble_sort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) { // 第 i 輪,確定第 n-i-1 位置的最終值
for (int j = 0; j < n - i - 1; j++) { // 相鄰比較交換
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
若某輪遍歷未發生任何交換,說明數列已有序,可立即結束:
void bubble_sort_opt(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int swapped = 0;
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
swapped = 1;
}
}
if (!swapped) break; // 本輪無交換,已有序
}
}
每輪遍歷中,最後一次交換的位置之後的元素已有序,下一輪只需遍歷到該位置:
void bubble_sort_opt2(int arr[], int n) {
int last_swap = n - 1;
while (last_swap > 0) {
int curr_swap = 0;
for (int j = 0; j < last_swap; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
curr_swap = j;
}
}
last_swap = curr_swap; // 下一輪邊界
}
}
| 指標 | 數值 | 說明 |
|---|---|---|
| 最好時間複雜度 | O(n) | 已有序數列,優化版單趟遍歷即結束 |
| 平均/最壞時間複雜度 | O(n²) | 逆序數列需完整比較交換 |
| 空間複雜度 | O(1) | 原地排序,僅需常數臨時變量 |
| 穩定性 | 穩定 | 相等元素不交換,相對順序不變 |
#include <stdio.h>
void bubble_sort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int swapped = 0;
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
swapped = 1;
}
}
if (!swapped) break;
}
}
void print_arr(const int arr[], int n) {
for (int i = 0; i < n; i++) printf("%d ", arr[i]);
printf("\n");
}
int main() {
int a[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(a) / sizeof(a[0]);
printf("排序前: "); print_arr(a, n);
bubble_sort(a, n);
printf("排序後: "); print_arr(a, n);
return 0;
}
qsort (C 標準庫)、std::sort (C++)、Timsort (Python/Java) 等 O(n log n) 算法。冒泡排序是排序算法入門的「Hello World」。掌握其雙層循環核心邏輯、提前終止優化、邊界縮減優化,並明確其O(n²) 時間複雜度限制,是每個程序員的必修課。實際開發中,請拥抱標準庫提供的高效排序。