冒泡排序及其簡單優化

1、理論上冒泡排序,每次從頭到尾把最大的數找到放最後面,重複該操作數組長度的次數後完成排序,時間複雜度O(n的平方) 總計循環精確次數爲 n*(n-1) 前面的n代表個數,每個數字都去跟所有數比較一次,後面的n-1位每個數的比較次數

代碼:

    /**
     * 理論上的冒泡排序
     * 時間複雜度 O(n的平方)
     */
    @Test
    public void BubbleSort (){

        int[] arr = {6, 3, 8, 2, 9, 1};
        for (int i = 0; i < arr.length; i++) {//外層循環控制排序趟數
            for (int j = 0; j < arr.length - 1 ; j++) {//內層循環控制每一趟排序多少次
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

2、實際上使用冒泡排序時,第一次內部循環交換完成後可以確定最大(小)的數已經在最後面,第二次循環時不需要再去判斷最後兩個數的大小。而且外層循環只用 n-1次,因爲最後一次沒有比較前已經把比最小的數大的全部排好序,做後一次比較沒必要進行。總計循環次數爲:(n-1)+(n-2)+(n-3)+ ... +1  化簡後得固定值  n*(n-1)\2(n-1) /2   代碼如下:

    /**
     * 
     * 實際上常見的冒泡排序的代碼大致張這個樣子
     */
    @Test
    public void BubbleSort (){

        int[] arr = {6, 3, 8, 2, 9, 1};
        for (int i = 0; i < arr.length - 1; i++) {//外層循環控制排序趟數
            for (int j = 0; j < arr.length - 1 -i; j++) {//內層循環控制每一趟排序多少次
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

3、冒泡排序的進階:冒泡排序爲蠻力排序法,不管是用1還是2的代碼執行次數基本上可以確定,跟裏面的數原本的順序並沒有關係。但是假定數原本就很有序的情況下,冒泡排序可以說是非常的慢。
假定冒泡排序執行至中間某一次的時候,排序已經完成,後面的for循環執行就是白白浪費時間
因此我們可以加一個flag,當某一次循環直至結束時數據都沒有發生交換,證明所有的數據已經有序,那麼直接退出循環,就可優化整個冒泡排序算法,特別是在整體數據順序比較統一的時候。總計循環次數在 n-1 ~n*(n-1)\2(n-1) /2 之間 ,最優時 循環次數爲 n-1 。代碼如下:

 

    @Test
    public void BubbleSort (){
        int index = 0; //循環執行次數

        int[] arr = { 1, 2, 3, 4, 5,6,7,8,9};
        for (int i = 0; i < arr.length - 1 ; i++) {//外層循環控制排序趟數
            boolean flag = true; //循環提前退出標誌位
            for (int j = 0; j < arr.length - 1 -i; j++) {//內層循環控制每一趟排序多少次
                index++;
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = false;
                }
            }
            if(flag){break;}
        }
        System.out.println("循環執行次數:"+index);

        for (int i = 0 ; i < arr.length  ; i++){ //遍歷數組打印
            System.out.print(arr[i]+"  ");
        }

    }

 

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