我也來聊一下冒泡排序


有一個數組 :

int array [] = {5,4,3,2,1};

現在要求從小到大進行排序,那么我們可以想象排序過后 應該是 {1,2,3,4,5}

那么 冒泡排序 的原理就是 :

每比較一輪,就把最大的放到最后面,這也是冒泡名稱的由來。

那么我們先做第一輪比較吧!

for (int i = 0; i < a.length - 1; i++){
    if(a[ i ] > [a + i]){ //如果a[i] 比 a[i+1]大的話,二者就交換順序
        int temp = a[ i + 1];
        a[i + 1] = a[ i ];
        a[ i ] = temp;
    }   
}    

來細分一下 這個比較的過程 :

 i = 0 ,a[0] 和 a[1]比較,完成后數組的順序應該是 :

4,5,3,2,1

 i = 1 ,a[1] 和 a[2]比較,比較完以后,數組的順序應該是 :

4,3,5,2,1

i = 2, a[2] 和 a[3]比較,比較完以后,數組的順序應該是:

4,3,2,5,1

i = 3, a[3] 和 a[4]比較,比較完以后,數組的順序應該是:

4,3,2,1,5

當i=4的時候,由於要判斷 i<a.length - 1,不滿足,故退出比較。

所以第一輪比較完以后,數組的順序應該是 {4,3,2,1,5}.

 

此時對比結果,還需要比較,那么到底需要比較幾輪呢?幾輪呢?輪呢?呢~~~~??

如果 “每次把最大的數字冒到最后去” 算一輪的話,那么在最極端情況下[比如本例],那么應該是n-1輪,那么又有同學問了,為什么是n-1輪呢?

那再舉個例子,2個數字 {2,1}比較的話,把大的放后面去要幾輪呢?1輪,也就是 2 - 1 輪,呵呵,推廣一下就是 n - 1輪了。

所以 冒泡的代碼應該是這個樣子的 :

 

1 for(int j = 0 ; j < a.length - 1; j++){ // a.length - 1 標示 n - 1輪
2     for (int i = 0; i < a.length - 1; i++){
3      if(a[ i ] > [a + i]){ //如果a[i] 比 a[i+1]大的話,二者就交換順序
4          int temp = a[ i + 1];
5          a[i + 1] = a[ i ];
6          a[ i ] = temp;
7      }   
8   } 
9 }

到這里冒泡其實已經結束了。

但是其實還有一個優化空間。。。

我們前面已經發現,

經過第一輪排序,最大的一個已經到最后一個位置了。。

經過第二輪排序,次大的一個已經到倒數第二個位置了。。

以此類推,所以每經過一輪排序,那么“對應的倒數位置”的數字其實已經不用對比了。。。

比如 經過第一輪排序,那么在進行第二輪排序的時候,倒數第一個其實已經不用對比了,因為再第一輪排序的時候,已經非常明確,最后一個就是最大的了。。

素以這里就有一個優化的地方 :

 

 for(int j = 0 ; j < a.length - 1; j++){ // a.length - 1 標示 n - 1輪
     for (int i = 0; i < a.length - 1 - j; i++){//這里減去一個 " j" ,那么每次比較 “對應的倒數位置”的數字就不會對比了
      if(a[ i ] > [a + i]){ //如果a[i] 比 a[i+1]大的話,二者就交換順序
          int temp = a[ i + 1];
          a[i + 1] = a[ i ];
          a[ i ] = temp;
      }   
   } 
 }

 

到這里冒泡應該比較完整了,那么自己寫的代碼自己肯定要測試的啦。。

那么怎么測試呢 ?

我來寫幾個用例吧 ,直接寫數組元素吧 :

a [] = {};

a [] = {0};

a [] = {-1,-2,0,2,1}

a [] = {5,4,3,2,1}

a [] = {1,2,3,4,5}

面試經常被問到。。而且因為這個錯過了幾個很好的機會。希望以后不會再因為這個被刷了,呵呵,2015,好運常來~


免責聲明!

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



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