冒泡排序的優化與誤區


冒泡排序(Bubble Sort)是一種簡單的排序算法。它重復地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重復地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端。

  冒泡排序算法的運作如下:

  1.  比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
  2.  對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最后一對。在這一點,最后的元素應該會是最大的數。
  3.  針對所有的元素重復以上的步驟,除了最后一個。
  4.  持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。

//-----------------------------------------------------

正常的冒泡排序代碼:

 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 }

 

 

 

 

具體的在代碼中的注釋已經詳細給出解釋。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM