排序演算法Java實現

liuawei發表於2018-11-14

本文會通過Java語言實現:氣泡排序,插入排序,選擇排序,歸併排序,快速排序,桶排序,計數排序,基數排序,希爾排序

1 分析排序演算法

1.1 執行效率

  • 最好的情況,最壞的情況,平均情況時間複雜度
  • 時間複雜度的係數,常數,低階
  • 比較次數和交換次數

1.2 演算法的記憶體消耗

演算法的記憶體消耗我們可以通過空間複雜度來度量。

原地排序演算法,就是特指空間複雜度是O(1)的排序演算法。

1.3 排序演算法的穩定性

如果序列中有值相等的元素, 經過排序之後,相等元素之間原有的先後順序不變化。

2 氣泡排序

穩定排序演算法,原地排序演算法,時間複雜度:O(n^2)

氣泡排序操作相鄰的兩個資料,每次冒泡操作都會對相鄰的兩個元素進行比較,看是否滿足大小關係。每次冒泡都能選出最大的或者最小的值。

    /**
     * 氣泡排序
     * @param arr
     * @return
     */
    public static int[] bubbleSort(int[] arr) {
        if (arr == null || arr.length == 0) {
            return null;
        }
        int n = arr.length;
        // 總共需要迴圈n次  每次通過冒泡 得到最大的
        for (int i = 0; i < n; i++) {
            // 因為上一次已經確定了最大的,所以需要遍歷的資料就是(n-1)-i
            boolean flag = true;
            for (int j = 0; j < (n - 1) - i ; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = false;
                }
            }
            // 因為冒泡 如果這次冒泡沒有資料沒有交換所以資料已經有序了,可以提前退出
            if (flag) {
                break;
            }
        }
        return arr;
    }

3 插入排序

穩定排序演算法,原地排序演算法,時間複雜度O(n^2)

根據,把位置的元素,插入在有序的集合中,插入的時候根據元素位置大小。

首先:講陣列中的資料分為兩個區間,已排序區間和未排序區間。初始已排序區間只有一個元素就是陣列的第一個元素。

/**
     * 插入排序
     * @param arr
     * @return
     */
    public static int [] insertSort(int [] arr){
        if (arr==null||arr.length==0) {
            return null;
        }
        int n = arr.length;
        // n從一1開始表示a[0]屬於有序序列
        for (int i = 1; i < n; i++) {
            // 當前需要比較的數字
            int value = arr[i];
            // 需要比較的次數
            int j = i-1;
            // 查詢插入的位置
            for (; j>=0; j--) {
                if (arr[j]>value) {
                    // 資料移動
                    arr[j+1] = arr[j];
                }else {
                    // 插入排序前面是有序序列,所有不需要移動資料的時候,直接跳出比較下個數字
                    break;
                }
            }
            // 插入資料
            arr[j+1] = value;
        }
        return arr;
    }

4 選擇排序

不是穩定排序演算法,原地排序演算法,時間複雜度是O(n^2)

每次會從未排序區間中找到最小元素,將其放到已排序區間的末尾

    /**
     * 選擇排序
     * @param arr
     * @return
     */
    public static int [] selectionSort(int [] arr){
        if (arr==null||arr.length==0) {
            return null;
        }
        int n = arr.length;
        int temp = 0;
        int minKey = 0;
        // 剛開始沒有有序區間,所以從0開始
        for (int i = 0; i < n; i++) {
            minKey = i;
            // 尋找無序區間最小的元素
            for (int j = i+1; j < n; j++) {
                if (arr[j]<arr[minKey]) {
                    minKey = j;
                }
            }
            // 交換位置   
            temp = arr[i];
            arr[i] = arr[minKey];
            arr[minKey] = temp;
        }
        return arr;
    }

未完,待續


相關文章