冒泡排序(Bubble Sort)是一種簡單的排序算法。它重復地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重復地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端。
冒泡排序算法的運作如下:
- 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
- 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最后一對。在這一點,最后的元素應該會是最大的數。
- 針對所有的元素重復以上的步驟,除了最后一個。
- 持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。
//-----------------------------------------------------
正常的冒泡排序代碼:
1 public class BubbleSort{ 2 public static void main(String[] args){ 3 int score[] = {67, 69, 75, 87, 89, 90, 99, 100}; 4 for (int i = 0; i < score.length -1; i++){ //最多做n-1趟排序 5 for(int j = 0 ;j < score.length - i - 1; j++){ //對當前無序區間score[0......length-i-1]進行排序(j的范圍很關鍵,這個范圍是在逐步縮小的) 6 if(score[j] < score[j + 1]){ //把小的值交換到后面 7 int temp = score[j]; 8 score[j] = score[j + 1]; 9 score[j + 1] = temp; 10 } 11 } 12 System.out.print("第" + (i + 1) + "次排序結果:"); 13 for(int a = 0; a < score.length; a++){ 14 System.out.print(score[a] + "\t"); 15 } 16 System.out.println(""); 17 } 18 System.out.print("最終排序結果:"); 19 for(int a = 0; a < score.length; a++){ 20 System.out.print(score[a] + "\t"); 21 } 22 } 23 }
//那么問題來了?在排序過程中發現后面的元素已經是排好序了,那么后面的繼續便利就是浪費了,因此增加flag標志位,進行提前終止
提高算法的效率
1 /** 2 * 原因,當冒泡排序發現元素已經是排序好了的時候,並不會停止這將會浪費時間復雜度。 3 * 分析:當把大的數不斷后移的時候,在下一次再次進行排序檢驗的時候發現當前已經是排好序的了,那么不再繼續循環直接跳出 4 * 這里節省的時間復雜度值得是:減少了for循環的次數:比如{1, 3, 2 ,9 ,4} 經過 5 * 第一次冒泡后變為{1,2,3,4,9},此時的flag仍為false,然后繼續下一波外層循環,flag此時為true了,但是內部for循環還是要走一遍 6 * 這個是必須的否則就會和第二種優化一樣不夠健壯,在內部for循環里面,沒有一次可以進入if判斷了,說明在已經排好的最大數的前面的數組已經為有序的了 7 * 此時才應該是break,這種優化只是部分上優化了冒泡。 8 */ 9 public class BubbleSortAnalyse { 10 11 public static int[] sort(int[] data) { 12 int temp; 13 boolean flag = false; 14 15 for (int i = 0; i < data.length - 1; i++) { 16 flag = true; 17 for (int j = 0; j < data.length - i - 1; j++) { 18 if (data[j] > data[j + 1]) { 19 temp = data[j]; 20 data[j] = data[j + 1]; 21 data[j + 1] = temp; 22 flag = false; 23 } 24 } 25 // 如果上一輪冒泡排序已經全部有序 26 // 即flag!=false,則直接退出,不用進行下一輪冒泡循環,提高效率,否則數組已經有序了,他還會繼續冒泡循環 27 if (flag) { 28 break; // 可以注釋這一行,單步測試或者查看i的值即可驗證 29 } 30 // System.out.println(i); 31 } 32 return data; 33 } 34 35 // 冒泡排序優化,通過flag進行判斷排序是否提前已經結束。 36 // 該優化存在缺陷,當最小的數可能還在后面已經排好序的數組中時就已經停掉了, 37 // 38 public static void BubbleSort(int[] arr) { 39 int n = arr.length; 40 int i, j, temp, flag; // temp臨時變量,flag是否提前結束的標志位 41 flag = 1;// flag等於1表示循環沒有結束,0表示循環已經結束 42 // 冒泡排序 43 for (i = 1; i < n && flag == 1; i++) { 44 for (j = 0; j < n - i; j++) { 45 // 如果以后的循環不改變flag的值,說明沒有發生數組交換 46 // 也就是說這個數組已經是排好序的了。 47 flag = 0; 48 if (arr[j] > arr[j + 1]) { 49 // 只要是有一次也需要置為1 50 flag = 1; 51 // 交換 52 temp = arr[j]; 53 arr[j] = arr[j + 1]; 54 arr[j + 1] = temp; 55 } 56 57 } 58 } 59 } 60 61 public static void main(String[] args) { 62 int[] arr = { 2, 3, 9, 1, 10 }; 63 // BubbleSort(arr); 64 int[] arr2 = sort(arr); 65 for (int i : arr2) { 66 System.out.println(i); 67 } 68 } 69 }
具體的在代碼中的注釋已經詳細給出解釋。