[數據結構]選擇排序算法和希爾排序算法詳解

選擇排序算法是經典算法之一,你可以想象你在打牌,每次拿到的一張牌就是待排序的一張,你需要每一次跟之前的牌進行比較,然後將這張牌插入到合適的位置。那麼選擇排序也是一樣,將整個數組看成兩個部分,有序部分和無序部分。現在需要將無序部分的數字跟有序部分進行比較,插入到正確的位置

下列代碼是插入排序的內層循環:

while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
    arr[insertIndex + 1] = arr[insertIndex];
    insertIndex--;
}

while循環中判斷用來控制當前數字是否比有序部分前一個數字小,和必須要滿足有序部分的前一個索引是大於0的否則就會出現越界。循環裏面進行數值的賦值。意義在於當判斷成立之後,則代表當前數字是比有序部分的數字小,那麼需要進行移位,即把前一個數字賦值給後一個數字,然後再將下標前移。下面放完整代碼:

public static void insertSort(int[] arr) {
    for (int i = 1; i < arr.length; i++) {
        //需要進行插入操作的數
        int insertVal = arr[i];
        int insertIndex = i - 1;
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
            arr[insertIndex + 1] = arr[insertIndex];
            insertIndex--;
        }
        arr[insertIndex + 1] = insertVal;
    }
}

最後來測試一下本算法在處理10w條數據的處理時間

public static void main(String[] args) {
    int[] arr = new int[100000];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = (int) (Math.random() * 8000000);
    }
    // System.out.println(Arrays.toString(arr));
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String start = sdf.format(new Date());
    System.out.println(start);
    insertSort(arr);

    String end = sdf.format(new Date());
    System.out.println(end);

}

最終的運行結果爲:
[數據結構]選擇排序算法和希爾排序算法詳解
但是選擇排序算法是可以進行優化的,舉個例子

{2,3,4,5,6,7,8,9,1} 像現在這組數據,如果按照傳統的插入排序,最後一位數字進行判斷和移位時會出現大量移位。那麼爲了解決這個問題就需要設置一個步長,利用步長將數組分爲多個小數組進行插入排序。這樣就可以將這個問題進行簡化。

具體代碼如下:

public static void shellSort(int[] arr) {
    for (int step = arr.length / 2; step > 0; step /= 2) {
        for (int i = step; i < arr.length; i++) {
            int j = i;
            int value = arr[i];
            if (arr[j] < arr[j - step]) {
                while (j - step >= 0 && value < arr[j - step]) {
                    arr[j] = arr[j - step];
                    j -= step;
                }
                arr[j] = value;
            }
        }
    }
}

代碼中第一層循環是控制步長循環,這樣就可以將數組分爲若干個小數組,在步長爲1時這時的數組就變成了一個基本有序的數組,這樣再對這個數組進行排序效率明顯就提升了許多。

最後來測試一下本算法在處理10w條數據的處理時間

public static void main(String[] args) {
    int[] arr = new int[100000];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = (int) (Math.random() * 8000000);
    }
    // System.out.println(Arrays.toString(arr));
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String start = sdf.format(new Date());
    System.out.println(start);
    shellSort(arr);

    String end = sdf.format(new Date());
    System.out.println(end);

}

最終的運行結果爲:
[數據結構]選擇排序算法和希爾排序算法詳解
可以很明顯得看出這個算法的效率還是很高的。

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