🔄 氣泡排序法完整教學
程式碼、原理與運作演示
📌 基本概念
氣泡排序法(Bubble Sort) 是一種簡單的排序演算法,它通過重複走訪要排序的數列,比較相鄰的兩個元素,如果順序不對就交換它們。隨著演算法的進行,最大的元素會逐漸「浮」到數列的末端,就像水中的氣泡一樣上升到水面。
這個演算法最適合用在教學和理解排序概念上,因為它直觀易懂,但在實際應用中性能不如其他排序演算法。
⚙️ 操作原理與動畫演示
輸入數列,點擊「開始排序動畫」即可觀察氣泡排序的每一步。
開始排序動畫
(可自訂數列,逗號分隔)
⚙️ 詳細運作原理
演算法步驟:
1
外層迴圈: 走訪整個數列 n-1 次(n 是數列長度)
2
內層迴圈: 在每次外層迴圈中,比較相鄰的元素對
3
比較與交換: 如果前一個元素大於後一個元素,就交換它們
4
持續重複: 持續進行直到整個數列排序完成(沒有再需要交換)
虛擬程式碼:
procedure bubbleSort(list : array of items)
n = length(list)
for i = 0 to n-1 do
for j = 0 to n-i-1 do
if list[j] > list[j+1] then
swap(list[j], list[j+1])
end if
end for
end for
end procedure
📊 具體例子 - 排序 [5, 2, 8, 1, 9]
初始陣列: [5, 2, 8, 1, 9]
第 1 輪:
比較 5 和 2 → 交換 → [2, 5, 8, 1, 9]
比較 5 和 8 → 無需交換 → [2, 5, 8, 1, 9]
比較 8 和 1 → 交換 → [2, 5, 1, 8, 9]
比較 8 和 9 → 無需交換 → [2, 5, 1, 8, 9 ]
9 已在正確位置
第 2 輪:
比較 2 和 5 → 無需交換 → [2, 5, 1, 8, 9]
比較 5 和 1 → 交換 → [2, 1, 5, 8, 9]
比較 5 和 8 → 無需交換 → [2, 1, 5, 8, 9 ]
8, 9 已在正確位置
第 3 輪:
比較 2 和 1 → 交換 → [1, 2, 5, 8, 9]
比較 2 和 5 → 無需交換 → [1, 2, 5, 8, 9 ]
2, 5, 8, 9 已在正確位置
第 4 輪:
數列已排序完成:[1, 2, 5, 8, 9 ]
💻 C語言完整程式碼
#include <stdio.h>
#include <string.h>
// 氣泡排序函數,用於排序字串陣列
void bubbleSort(char arr[][50], int n) {
int i, j;
char temp[50];
// 外層迴圈:走訪 n-1 次
for (i = 0; i < n-1; i++) {
// 內層迴圈:比較相鄰元素
for (j = 0; j < n-i-1; j++) {
// 如果前一個元素大於後一個,就交換
if (strcmp(arr[j], arr[j+1]) > 0) {
// 複製第 j 個元素到暫存
strcpy(temp, arr[j]);
// 複製第 j+1 個元素到第 j 個
strcpy(arr[j], arr[j+1]);
// 複製暫存到第 j+1 個
strcpy(arr[j+1], temp);
}
}
}
}
// 主程式
int main() {
// 定義城市陣列
char cities[][50] = {"Taipei", "Kaohsiung", "Taichung", "Tainan", "Hsinchu"};
int n = sizeof(cities)/sizeof(cities[0]);
// 顯示原始陣列
printf("原始城市列表: ");
for (int i = 0; i < n; i++) {
printf("%s ", cities[i]);
}
printf("\n\n");
// 執行氣泡排序
bubbleSort(cities, n);
// 顯示排序後的陣列
printf("排序後的城市列表: ");
for (int i = 0; i < n; i++) {
printf("%s ", cities[i]);
}
printf("\n");
return 0;
}
程式輸出:
原始城市列表: Taipei Kaohsiung Taichung Tainan Hsinchu
排序後的城市列表: Hsinchu Kaohsiung Taichung Tainan Taipei
📈 效能分析
複雜度分類
說明
時間複雜度
O(n²) - 需要 n-1 次外層迴圈,每次內層迴圈最多執行 n-i-1 次,總共約 n×n/2 = n²/2 ≈ O(n²)
空間複雜度
O(1) - 只使用常數個額外變數(如 temp, i, j),不需要額外的陣列
穩定性
✓ 穩定排序 - 相同元素的相對順序不會改變
排序方式
○ 原地排序 - 不需要額外的記憶體空間
✅ 優缺點分析
✓ 優點:
簡單易懂: 演算法邏輯直觀,新手容易理解
原地排序: 只需要常數級別的額外空間 O(1)
穩定排序: 相同值的元素相對順序不變
自適應: 已排序的陣列時間複雜度為 O(n)
易於實現: 程式碼簡潔,容易除錯
✗ 缺點:
效率低: 平均時間複雜度為 O(n²),不適合大型資料集
比較次數多: 即使資料已排序,仍需進行多次比較
交換次數多: 會進行大量數據移動操作
不適合實務應用: 當數據量大時,效能顯著下降
🎯 應用場景
教育用途: 學習排序演算法的基礎概念
小規模資料: 當資料量很小(< 100 元素)時
幾乎已排序: 當資料已大致排序時
演算法理解: 理解時間複雜度和交換算法的概念
簡單實現: 當簡單易懂比效率更重要時
🔀 與其他排序算法的比較
演算法
時間複雜度 (平均)
空間複雜度
穩定性
應用
氣泡排序
O(n²)
O(1)
✓ 穩定
教育用途
選擇排序
O(n²)
O(1)
✗ 不穩定
簡單場景
插入排序
O(n²)
O(1)
✓ 穩定
小規模資料
快速排序
O(n log n)
O(log n)
✗ 不穩定
一般應用
歸併排序
O(n log n)
O(n)
✓ 穩定
大型資料集
堆本排序
O(n log n)
O(1)
✗ 不穩定
需要保證效率
📝 總結
氣泡排序法是學習排序演算法時的良好起點,它清楚地演示了排序的基本概念。雖然在實務應用中因為效率問題而較少使用,但它對於理解演算法設計和複雜度分析仍然非常有價值。
當您需要排序小規模資料或進行教學演示時,氣泡排序法是一個簡單且實用的選擇。但對於生產環境或大型資料集,應該選擇效率更高的演算法如快速排序或歸併排序。