排序(二):冒泡排序法

一. 基本思想
    通過從左到右不斷交換逆序的相鄰元素,在一輪的交換之後,可以讓未排序的元素上浮到右側。在一輪循環中,如果沒有發生交換,就說明數組已經是有序的,此時可以直接退出。

二. 代碼實現

  • 版本一
/**
 - <br>冒泡排序</br>
 */
public class BubbleSort {

    /**
     * 外層循環控制比較的輪數,內層循環進行依次相鄰元素的比較
     * 在第一輪比較中,最大的元素冒泡到了最後的位置;
     * 在第二輪比較中,第二大的元素冒泡到了倒數第二個位置;
     * 依此類推。
     * @param arr
     */
    public static void sort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);
                }
            }
        }
    }
	
    private static void swap(int[] arr, int i, int j) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
}
  • 版本二
/**
 * <br>冒泡排序</br>
 */
public class BubbleSort2 {

        public static void sort(int[] arr) {
        int n = arr.length;
        boolean swap;
        do {
            /**
            * 這裏的swap主要考慮的 如果數組是近乎有序的,
            * 那麼在某輪比較後,沒有產生swap操作,即剩下的
            * 未排序的元素已經是有序的了,就不用再比較了。
            */
            swap = false;
            for (int i = 0; i < n - 1; i++) {
                if (arr[i] > arr[i + 1]) {
                    swap(arr, i, i + 1);
                    swap = true;
                }
            }
            /**
             *  每一趟Bubble Sort都將最大的元素放在了最後的位置
             *  所以下一次排序, 最後的元素可以不再考慮
             */
            n--;
        } while (swap);
    }
    
    private static void swap(int[] arr, int i, int j) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
}
/**
 * <br>冒泡排序優化</br>
 */
public class BubbleSort3 {

    /**
     * 按照之前升序排列,每輪循環將剩下元素中最大的元素調到最後.
     * 考慮這樣的情況:假設在前面未排序的元素中,後面靠近尾端的元素已經是有序的了,
     * 但是之前的做法還是會每次把這些元素包括進去遍歷.
     * 例如:原始一組數據: 3,6,2,4,5
     * 第一輪排序後:3,2,4,5,6
     * 按照之前的思想:接下來的一輪迴會在剩下的未排序序列 3,2,4,5中找出最大的元素調到最後,
     * 但是4,5本身是有序的,他們在上一輪的遍歷中並沒有交換位置,所以我們完全可以依據上一輪的遍歷設置個記錄
     * 最後交換順序的指針,然後只需要遍歷這個指針之前的元素.
     *
     * @param arr
     */
    public static void sort(int[] arr) {
        int n = arr.length;
        int lastSwapIndex;
        do {
            //重置,清零
            lastSwapIndex = 0;
            for (int i = 0; i < n - 1; i++) {
                if (arr[i] > arr[i+1]){
                    swap(arr,i,i+1);
                    // 記錄最後一次的交換位置,在此之後的元素在下一輪掃描中均不考慮,注意這裏的臨界點
                    lastSwapIndex = i+1;
                }
            }
            n = lastSwapIndex;
        } while (lastSwapIndex > 0);
    }

    private static void swap(int[] arr, int i, int j) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章