死磕演算法之氣泡排序

javenshi發表於2018-06-29
版權宣告:本文為博主原創文章,未經博主允許不得轉載。部落格源地址為zhixiang.org.cn https://blog.csdn.net/myFirstCN/article/details/80851029

學習更多演算法系列請參考文章:死磕演算法之彙總篇

氣泡排序在排序演算法中效率算最慢的一類了,但是因為它簡單的緣故仍然是工作1-3年的程式設計師面試經常會碰到的演算法問題,今天就來給大家分析一下氣泡排序的排序流程。

假如我們現在要排序的陣列為[3,1,0,2,8,4,2]那麼我們第一輪排序為

  1. 比較3和1,發現3比1大,那麼我們就交換3和1,陣列變成了[1,3,0,2,8,4,2]
  2. 比較3和0,發現3比0大,那麼我們就交換3和0,陣列變成了[1,0,3,2,8,4,2]
  3. 比較3和2,發現3比2大,那麼我們就交換3和2,陣列變成了[1,0,2,3,8,4,2]
  4. 比較3和8,發現3沒有8大,那麼不操作,陣列還是[1,0,2,3,8,4,2]
  5. 比較8和4,發現8比4大,那麼我們就交換8和4,陣列變成了[1,0,2,3,4,8,2]
  6. 比較8和2,發現8比2大,那麼我們就交換8和2,陣列變成了[1,0,2,3,4,2,8]

現在第一輪的排序已經完成了,我們就篩選出來了最大值8,此時數字8已經在陣列最後的位置了,下一輪排序我們就可以排除它了。

第二輪排序為:

  1. 比較1和0,發現1比0大,那麼我們就交換1和0,陣列變成了[0,1,2,3,4,2,8]
  2. 比較1和2,發現1沒有2大,那麼不操作,陣列還是[0,1,2,3,4,2,8]
  3. 比較2和3,發現2沒有3大,那麼不操作,陣列還是[0,1,2,3,4,2,8]
  4. 比較3和4,發現3沒有4大,那麼不操作,陣列還是[0,1,2,3,4,2,8]
  5. 比較4和2,發現4比2大,那麼我們就交換4和2,陣列變成了[0,1,2,3,2,4,8]

現在第二輪排序完成了,陣列最後的4和8是不是已經有序了呢。

聰明的你是不是已經發現了氣泡排序的規律了呢,那麼你能用程式碼去手寫一下實現麼?

int []a=new int[]{3,1,0,2,8,4,2};
int i,j;
int flag;                 // 標記
for (i=a.length-1; i>0; i--) {
    flag = 0;            // 初始化標記為0
    // 將a[0...i]中最大的資料放在末尾
    for (j=0; j<i; j++) {
        if (a[j] > a[j+1]) {
            // 交換a[j]和a[j+1]
            int tmp = a[j];
            a[j] = a[j+1];
            a[j+1] = tmp;
            flag = 1;    // 若發生交換,則設標記為1
        }
    }

    if (flag==0)
        break;            // 若沒發生交換,則說明數列已有序。
}
for (int ii:a){
    System.out.print(ii+",");
}

上方程式碼就是我們氣泡排序的一個簡單實現了。你手寫的是不是比我的更強呢。

上方的程式碼還有一個flag我們沒有說到,不知道你注意到了麼,本身待排序的陣列是需要陣列長度-1大輪排序才能得出結果,但是我們這個陣列在第三輪排序完成後就已經有序了,第四輪的時候其實內層的迴圈是沒有進去的,那麼我們是不是可以得出結論,既然第四輪沒有進行排序那麼再後面的排序是不是也不需要了,所以我們使用了一個flag標記來避免多餘的操作。

一個簡單的氣泡排序講完了。在這裡溫馨提示大家,學習演算法時,我們沒必要拘泥於程式碼的實現,那沒有意義。我的建議就是深入理解步驟,當你理解步驟以後程式碼是隨你怎麼玩都可以的。


相關文章