深入探究Java數據結構與算法系列(三)——冒泡排序(基礎算法)

    引言:     

       在切入到算法這個領域之前,像很多人一樣都會去了解這個算法的原理以及它的實現代碼。也正是說明了它是總多算法當中的基礎中基礎,也是帶領我們深入到各個算法當中不可或缺的一個步驟,如果有過一點算法基礎的人或缺會有個印象,冒泡排序用到了兩個for循環,那麼一般我們都認爲它的時間複雜度爲O(N2),,那麼今天我們來探究一下冒泡排序算法的實現。

    基礎原理:

        這個名詞的由來很好理解,一般河水中的冒泡,水底剛冒出來的時候是比較小的,隨着慢慢向水面浮起會逐漸增大,這物理規律我不作過多解釋,大家只需要瞭解即可。

  冒泡算法的運作規律如下:

  ①、比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。

  ②、對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數(也就是第一波冒泡完成)。

  ③、針對所有的元素重複以上的步驟,除了最後一個。

  ④、持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。

下面是代碼的實現:

package sort;

/**
 * @author hegx
 */
public class BubbleSort {
    /**
     * 冒泡排序
     * @param array
     * @return array
     */
    private static int[] bubbleSort(int[] array) {
        int temp;
        display(array);
        System.out.println("數組內容開始排序....");
        for (int i = 1; i < array.length; i++) {
            //標識排序成功,true排好序,否則false
            boolean flag = true;
            for (int j = 0; j < array.length-1; j++) {
                if (array[j] > array[j+1]) {
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                    flag = false;
                }
            }
            if (flag==true){
                break;
            }
            System.out.print("第"+i+"論排序結果:");
            display(array);
        }
        System.out.println("冒泡法排序結束");
        return array;
    }

    /**
     * 遍歷打印數組
     * @param array
     */
    private static void display(int[] array){
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+"\t");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[]  array = {3,9,5,1,8,2,6,7,4};
        bubbleSort(array);
        display(array);
    }

}
程序運行結果:

 

本來應該是 8 輪排序的,這裏我們只進行了 5輪排序,因爲第 5 輪排序之後已經是有序數組了。

冒泡排序解釋:

  冒泡排序是由兩個for循環構成,第一個for循環的變量 i 表示總共需要多少輪比較,第二個for循環的變量 j 表示每輪參與比較的元素下標【0,1,......,length-i】,因爲每輪比較都會出現一個最大值放在最右邊,所以每輪比較後的元素個數都會少一個,這也是爲什麼 j 的範圍是逐漸減小的。相信大家理解之後快速寫出一個冒泡排序並不難。

  冒泡排序性能分析:

  假設參與比較的數組元素個數爲 N,則第一輪排序有 N-1 次比較,第二輪有 N-2 次,如此類推,這種序列的求和公式爲:

  (N-1)+(N-2)+...+1 = N*(N-1)/2

  當 N 的值很大時,算法比較次數約爲 N2/2次比較,忽略減1。

  假設數據是隨機的,那麼每次比較可能要交換位置,可能不會交換,假設概率爲50%,那麼交換次數爲 N2/4。不過如果是最壞的情況,初始數據是逆序的,那麼每次比較都要交換位置。

  交換和比較次數都和N2 成正比。由於常數不算大 O 表示法中,忽略 2 和 4,那麼冒泡排序運行都需要 O(N2) 時間級別。

  其實無論何時,只要看見一個循環嵌套在另一個循環中,我們都可以懷疑這個算法的運行時間爲 O(N2)級,外層循環執行 N 次,內層循環對每一次外層循環都執行N次(或者幾分之N次)。這就意味着大約需要執行N2次某個基本操作。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章