概念
冒泡排序(Bubble Sort):重復地循環要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。循環數列的工作是重復地進行直到沒有再需要交換,也就是說該數列已經排序完成。
原理
- 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
- 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最后一對。在這一點,最后的元素應該會是最大的數或者是最小的。
- 針對所有的元素重復以上的步驟,除了最后一個。
- 持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。
例子為從小到大排序,
原始待排序數組| 6 | 2 | 4 | 1 | 5 | 9 |
第一趟排序(外循環)
第一次兩兩比較6 > 2交換(內循環)
交換前狀態| 6 | 2 |4 | 1 | 5 | 9 |
交換后狀態| 2 | 6 |4 | 1 | 5 | 9 |
第二次兩兩比較,6 > 4交換
交換前狀態| 2| 6 | 4 |1 | 5 | 9 |
交換后狀態| 2| 4 | 6 |1 | 5 | 9 |
第三次兩兩比較,6 > 1交換
交換前狀態| 2 | 4| 6 | 1 |5 | 9 |
交換后狀態| 2 | 4| 1 | 6 |5 | 9 |
第四次兩兩比較,6 > 5交換
交換前狀態| 2 | 4 | 1| 6 | 5 |9 |
交換后狀態| 2 | 4 | 1| 5 | 6 |9 |
第五次兩兩比較,6 < 9不交換
交換前狀態| 2 | 4 | 1 | 5| 6 | 9 |
交換后狀態| 2 | 4 | 1 | 5| 6 | 9 |
第二趟排序(外循環)
第一次兩兩比較2 < 4不交換
交換前狀態| 2 | 4 |1 | 5 | 6 | 9 |
交換后狀態| 2 | 4 |1 | 5 | 6 | 9 |
第二次兩兩比較,4 > 1交換
交換前狀態| 2| 4 | 1 |5 | 6 | 9 |
交換后狀態| 2| 1 | 4 |5 | 6 | 9 |
第三次兩兩比較,4 < 5不交換
交換前狀態| 2 | 1| 4 | 5 |6 | 9 |
交換后狀態| 2 | 1| 4 | 5 |6 | 9 |
第四次兩兩比較,5 < 6不交換
交換前狀態| 2 | 1 | 4| 5 | 6 |9 |
交換后狀態| 2 | 1 | 4| 5 | 6 |9 |
第三趟排序(外循環)
第一次兩兩比較2 > 1交換
交換后狀態| 2 | 1 |4 | 5 | 6 | 9 |
交換后狀態| 1 | 2 |4 | 5 | 6 | 9 |
第二次兩兩比較,2 < 4不交換
交換后狀態| 1| 2 | 4 |5 | 6 | 9 |
交換后狀態| 1| 2 | 4 |5 | 6 | 9 |
第三次兩兩比較,4 < 5不交換
交換后狀態| 1 | 2| 4 | 5 |6 | 9 |
交換后狀態| 1 | 2| 4 | 5 |6 | 9 |
第四趟排序(外循環)無交換
第五趟排序(外循環)無交換
排序完畢,輸出最終結果1 2 4 5 6 9
算法描述(C語言)
void bubble_sort(int *a, int n) {
int temp;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n -1 - i; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
int main() {
int number[] = {6, 5, 1, 7, 8, 9, 5};
int len = sizeof(number)/sizeof(int);
bubble_sort(number, len);
for (int i = 0; i < len; i++) {
printf("%d", number[i]);
}
printf("\n");
return 0;
}
算法穩定性
兩個相等的元素(不管是相鄰還是不相鄰),排序結束后都不會發生未知交換,所以冒泡排序是****穩定****的排序算法。
算法分析
時間復雜度:最壞:O(n2) 最好:O(n-1)