上篇的 Selection Sorting 是掃全部的集合,然後把最小值固定在左側,這個 Bubble Sorting 有點相反的味道,它一樣從左側開始,逐一跟下一個元素比較,比較大就換,慢慢爬到最右邊固定住,最大值慢慢冒出頭的感覺,就像冒泡一樣所以叫泡沫排序,這形容感覺蠻牽強的。
雖然 Bubble 跟 Selection 都用 Nested Loop,所以有相同的複雜度 O(n^2),但 Bubble 的效能相對差很多,因為以同個集合的條件為例,最差情況下兩者 swap 的操作次數差很多,因為 Selection 最差了不起每輪 swap 一次,但 Bubble 有可能每次的判斷都要 swap,一輪下來就換了 n - 1 次了,最壞要到 n(n - 1)/2 次,如果 n=100 的話,
Selection 最多 99 次,Bubble 最多 4950 次。交換的成本比判斷高很多,一次 swap 要 3 次記憶體操作:
int temp = arr[i]; // 1次讀取
arr[i] = arr[j]; // 1次讀取 + 1次寫入
arr[j] = temp; // 1次寫入
判斷是 CPU 運算,swap 要記憶體讀寫,開銷較大。
public static List<Integer> sortList(List<Integer> unsortedList) {
int n = unsortedList.size();
for (int i = n - 1; i >= 0; i--) {
boolean swapped = false;
for (int j = 0; j < i; j++) {
if (unsortedList.get(j) > unsortedList.get(j + 1)) {
int temp = unsortedList.get(j);
unsortedList.set(j, unsortedList.get(j + 1));
unsortedList.set(j + 1, temp);
swapped = true;
}
}
if (!swapped)
return unsortedList;
}
return unsortedList;
}
第一層是代表的每一輪的終點。
第二層是冒泡到終點的過程。
最後沒泡泡就跳出結束了。
基本上 Bubble 沒實際使用價值,主要是教學價值而已。