1. 程式人生 > >資料結構與演算法--蠻力法之氣泡排序與時間複雜度分析(java)

資料結構與演算法--蠻力法之氣泡排序與時間複雜度分析(java)

蠻力法

        蠻力法又稱窮舉法和列舉法,是一種簡單直接地解決問題的方法,常常直接基於問題的描述,所以蠻力法也是最容易應用的方法。但是蠻力法所設計的演算法時間特性往往是比較低的,典型的指數時間演算法一般都是通過蠻力搜尋得到的。所謂的指數時間演算法,是指輸入資料的數量依線性成長,所花的時間將會以指數成長。

應用

       常用的蠻力法應用演算法有我們比較熟悉的氣泡排序、選擇排序。

氣泡排序

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

       對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最後一對。在這一步,最後的元素應該會是最大的數。

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

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

       當然,你也可以從大到小排序,也可以從後向前冒泡。其特徵操作是相鄰元素的比較和交換。

實現步驟

       接下來,實現氣泡排序,基於將最大的值排到最後。初始程式碼如下:

    /**
     * @Author: AndyLin
     * @Title: bubbleSort
     * @Description: 氣泡排序
     * @param: array
     */
    public static void bubbleSort(int[] array){
        for(int i = array.length-1; i > 0; i--){
            for(int j = 0; j < i; j++){
                if(array[j] > array[j+1]){
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }
    }

時間複雜度分析

         若陣列初始狀態是正序的,一趟掃描即可完成排序。所需的關鍵字比較次數C和記錄移動次數M,均達到最小值:

Cmin = n-1,Mmin = 0,即得出最理想的狀態,時間複雜度為O(n) 。

        若陣列初始狀態是反序的,需要進行n-1趟排序。每趟排序要進行n-i次關鍵字的比較(1≤i≤n-1),且每次比較都必須移動記錄三次來達到交換記錄位置。在這種情況下,比較和移動次數均達到最大值:

Cmax = n(n-1)/2,Mmax = 3n(n-1)/2,計算複雜度的原則,去掉常數,去掉最高項係數,即最壞的情況,時間複雜度為O(n^2)。

效能改進

        當外層迴圈第一次完成後,排序便完成了,然後後面的迴圈只有比較,而沒有資料交換。當一次外層迴圈中,相鄰的元素沒有發生資料交換,即說明陣列已經是有序的了,這時可以跳出迴圈。

/**
     * @Author: AndyLin
     * @Title: bubbleSort
     * @Description: 氣泡排序
     * @param: array
     */
    public static void bubbleSort(int[] array){
        for(int i = array.length-1; i > 0; i--){
            boolean flag = true;
            for(int j = 0; j < i; j++){
                if(array[j] > array[j+1]){
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                    flag = false;//標記資料交換
                }
            }
            if(flag){
                break;//對於一個已經有序的陣列,演算法完成第一次外層迴圈後就會返回
           }
        }
    }