冒泡排序通過重複遍歷數組,比較相鄰元素並交換順序,使較大元素像氣泡一樣逐步「浮」到數組末端。每輪遍歷確定一個最大值位置。
public static void bubbleSortBasic(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) { // 趟數
for (int j = 0; j < n - 1 - i; j++) { // 無序區範圍逐輪縮小
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
若某輪遍歷未發生任何交換,說明數組已有序,直接結束。
public static void bubbleSortOptimized(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
boolean swapped = false; // 標記本輪是否交換
for (int j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
swapped = true;
}
}
if (!swapped) break; // 本輪無交換,已有序
}
}
最後一次交換後的元素必然已有序,下輪只需遍歷到該位置。
public static void bubbleSortAdvanced(int[] arr) {
int n = arr.length;
int lastSwap = n - 1;
while (lastSwap > 0) {
int currentSwap = 0;
for (int j = 0; j < lastSwap; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
currentSwap = j; // 記錄最後交換位置
}
}
lastSwap = currentSwap; // 下輪邊界縮小
}
}
| 指標 | 基礎版 | 優化版 | 進階版 |
|---|---|---|---|
| 最好情況(已有序) | O(n²) | O(n) ⭐ | O(n) |
| 最壞情況(逆序) | O(n²) | O(n²) | O(n²) |
| 平均情況 | O(n²) | O(n²) | O(n²) |
| 空間複雜度 | O(1) | O(1) | O(1) |
| 穩定性 | 穩定(相等元素不交換) | ||
基礎版: ~4200 ms
優化版: ~2100 ms (有序時 ~1 ms)
進階版: ~1800 ms
Arrays.sort: ~15 ms (雙軸快排 + 歸併)
Arrays.sort() / Collections.sort()冒泡排序雖非實戰首選,但作為入門排序算法極具價值:
// 一行調用 JDK 高性能排序(生產代碼標準寫法)
Arrays.sort(arr); // 基本類型:雙軸快排
Arrays.sort(objArr); // 物件類型:TimSort(穩定、自適應)
掌握冒泡排序的演進歷程,能幫助你更深刻理解現代高性能排序算法的設計智慧。