冒泡排序 以其「大元素像氣泡一樣逐漸浮到頂端」的形象過程著稱。雖然效率不高,但因思路簡單、代碼極短,成為入門排序算法的經典教材。
#include#include #include #define N 10 int main() { int a[N], i, j, t; srand((unsigned)time(NULL)); printf("隨機產生 10 個 100 以內的數:\n"); for (i = 0; i < N; i++) { a[i] = rand() % 100; printf("%d ", a[i]); } printf("\n"); // 冒泡排序核心邏輯 for (j = 1; j <= N-1; j++) { // 控制輪數 for (i = 0; i <= N-1-j; i++) { // 每輪比較範圍遞減 if (a[i] > a[i+1]) { // 升序:前大後小則交換 t = a[i]; a[i] = a[i+1]; a[i+1] = t; } } } printf("排序後輸出:\n"); for (i = 0; i < N; i++) { printf("%d ", a[i]); } printf("\n"); return 0; }
隨機產生 10 個 100 以內的數: 82 15 67 3 91 44 28 76 50 11 排序後輸出: 3 11 15 28 44 50 67 76 82 91
| 特性 | 描述 |
|---|---|
| 時間複雜度 | 最好 O(n)(已有序+優化標誌),最壞/平均 O(n²) |
| 空間複雜度 | O(1),原地排序 |
| 穩定性 | 穩定(相等元素不交換,相對順序不變) |
| 比較次數 | 固定 n(n-1)/2 次(無優化時) |
| 適用場景 | 教學演示、極小數據量、近乎有序數據 |
// 優化 1:設置標誌位,若某輪無交換則提前結束
for (j = 1; j <= N-1; j++) {
int swapped = 0;
for (i = 0; i <= N-1-j; i++) {
if (a[i] > a[i+1]) {
t = a[i]; a[i] = a[i+1]; a[i+1] = t;
swapped = 1;
}
}
if (!swapped) break; // 本輪無交換,說明已有序
}
// 優化 2:記錄最後交換位置,下一輪只需掃描到該位置
int lastSwap = N-1;
for (j = 1; j <= N-1; j++) {
int swapped = 0;
for (i = 0; i < lastSwap; i++) {
if (a[i] > a[i+1]) {
t = a[i]; a[i] = a[i+1]; a[i+1] = t;
swapped = 1;
lastSwap = i; // 記錄最後交換位置
}
}
if (!swapped) break;
}
冒泡排序是理解「比較交換」類排序的最佳切入點。雖然實際工程極少直接使用,但其優化思想(標誌位、縮小範圍)體現了算法改進的通用思路:減少無效比較、利用已有序信息。掌握冒泡排序及其優化,為學習快速排序、希爾排序打下堅實基礎。