排序演算法之氣泡排序
簡介
氣泡排序(Bubble Sort),是一種電腦科學領域的較簡單的排序演算法。
它重複地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果順序(如從大到小、首字母從Z到A)錯誤就把他們交換過來。走訪元素的工作是重複地進行直到沒有相鄰元素需要交換,也就是說該元素列已經排序完成。
這個演算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端(升序或降序排列),就如同碳酸飲料中二氧化碳的氣泡最終會上浮到頂端一樣,故名“氣泡排序”。
基本思想
(1)比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
(2)對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。
(3)針對所有的元素重複以上的步驟,除了最後一個。
(4)持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
排序過程
此處排序資料:{29,10,14,37,13,14}
程式碼實現
/** * 氣泡排序 * @Author distance */ public class BubbleSort { public static void sort(int[] num) { int temp; for (int i = 0; i < num.length - 1; i++) { for (int j = 0; j < num.length - i -1; j++) { if (num[j] > num[j+1]) { temp = num[j]; num[j] = num[j+1]; num[j+1] = temp; } } } } public static void main(String[] args) { int[] num = {29,10,14,37,13,14}; BubbleSort.sort(num); for (int i = 0; i < num.length; i++) { System.out.print(num[i] + " "); } } }
程式碼優化
有沒有更優化的實現方式呢?
我們先來分析一下,結合程式碼我們發現氣泡排序有兩次for迴圈,這不是一個高效的演算法。如果說我們能夠減少冒泡的次數,則可以極大的提升演算法的執行效率。
其實我們只要結合氣泡排序演算法的核心思想後半部分:比較交換相鄰的元素。如果在一輪冒泡中,沒有發生相鄰元素的交換,那說明序列已經有序了,不管後面還剩下多少次冒泡,我們都不需要再進行冒泡下去了。這樣就減少了冒泡的次數。
關於減少冒泡次數的分析,如果你暫時沒有理解,沒有關係。請看下面的程式碼實現。
/** * 氣泡排序優化 * @Author distance */ public class BubbleSort { public static void sort(int[] num) { int temp; for (int i = 0; i < num.length - 1; i++) { boolean flag = false; // 設定標誌位 for (int j = 0; j < num.length - i - 1; j++) { if (num[j] > num[j+1]) { temp = num[j]; num[j] = num[j+1]; num[j+1] = temp; flag = true; // 交換了 } } if (!flag) { // 未交換,已經有序了,停止排序 break; } } } public static void main(String[] args) { int[] num = {29,10,14,37,13,14}; BubbleSort.sort(num); for (int i = 0; i < num.length; i++) { System.out.print(num[i] + " "); } } }
演算法分析
時間複雜度
如果初始狀態已經是正序的,一趟掃描即可完成排序。所需的關鍵字比較次數為 n-1 次和移動次數為 0,均達到最小值。所以,氣泡排序最好的時間複雜度為 O(n)。
如果初始狀態是反序的,需要進行 n-1 趟排序。每趟排序要進行 n-i 次關鍵字的比較 (1≤i≤n-1),且每次比較都必須移動數字三次來達到交換位置。在這種情況下,比較和移動次數均達到最大值。
氣泡排序的最壞時間複雜度為 O(n^2)。
綜上,因此氣泡排序總的平均時間複雜度為 O(n^2)。
演算法穩定性
氣泡排序就是把小的元素往前調或者把大的元素往後調。比較是相鄰的兩個元素比較,交換也發生在這兩個元素之間。
所以,如果兩個元素相等,是不會再交換的;如果兩個相等的元素沒有相鄰,那麼即使通過前面的兩兩交換把兩個相鄰起來,這時候也不會交換,所以相同元素的前後順序並沒有改變。
所以氣泡排序是一種穩定排序演算法。