插入排序

直接插入排序

將待排序序列分爲有序區和無序區,將無序區的元素逐一插入到有序區合適的位置上,直到所有有序java

相似玩牌時整理排的過程。 算法

直接插入排序步驟 shell

1.以數組第一個元素爲有序區。 數組

2.將無序區的第一個元素關鍵碼,插入到有序區。 blog

  • 尋找關鍵碼在有序區的目標位置
  • 插入關鍵碼

重複步驟2,直至所有有序。 排序

直接插入排序演示ip

clip_image001

算法分析 get

clip_image002

直接插入排序-java實現

    /**
     * 直接插入排序的分步理解
     * 
     * @param arr
     */

    public static void straightInsertionSort_step(int[] arr) {
        int size = arr.length;
        for (int i = 1; i < size; i++) { // arr[i]爲關鍵碼
            int destIndex = 0; // 插入的目標下標
            int key = arr[i]; // 保存關鍵碼
            // 遍歷尋找destIndex
            for (int j = i - 1; j >= 0; j--) {
                if (arr[j] <= key) { // 若是關鍵碼>=序區元素j,則插入j以後,不然,插入0下標
                    destIndex = j + 1;
                    break;
                }
            }
            // 後移記錄
            for (int j = i - 1; j >= destIndex; j--) {// 從前向後會覆蓋
                arr[j + 1] = arr[j];
            }
            // 插入
            arr[destIndex] = key;
            System.out.print("第 " + i + "輪 :" + Arrays.toString(arr));
            System.out.println("\tdestIndex:" + destIndex);
        }
    }

    /**
     * 直接插入排序
     * 
     * @param arr
     */
    public static void straightInsertionSort(int[] arr) {
        int size = arr.length;
        for (int i = 1; i < size; i++) {         // 外層控制輪數
            int key = arr[i];             // arr[i]爲關鍵碼
            int j = i - 1;
            for (; j >= 0 && key < arr[j]; j--){    //若是關鍵碼>=序區元素j,則插入j之
                arr[j + 1] = arr[j];        // 在尋找關鍵碼插入位置的同時將元素後移
            }
            arr[j + 1] = key;             // 插入目標位置
            System.out.print("第 " + i + "輪 :" + Arrays.toString(arr));
            System.out.println("\tdestIndex:" + (j + 1));
        }
    }

希爾排序

希爾排序是對直接插入排序的一種改進,着眼於: it

  • 若排序記錄按關鍵碼基本有序,直接插入排序的效率很高
  • 記錄個數少,直接插入排序效率高。由於直接插入排序時間複雜度爲O(n^2),n越小,效率越高。

希爾排序思想: io

  • 把記錄按步長 gap 分組,對每組記錄採用直接插入排序方法進行排序。保證整個序列基本有序。
  • 隨着步長逐漸減少,所分紅的序列包含的記錄愈來愈多,當步長的值減少到 1 時,全部記錄合成爲一組,通過直接插入排序後,構成一組有序記錄,則完成排序。

開始時增量的取值較大,每一個子序列記錄個數少,排序效率較高;後來增量逐步縮小,每一個子序列中的記錄個數增長,但已經基本有序,故排序效率也較高。

希爾排序演示:

clip_image003

算法分析

clip_image004

希爾排序-java實現

    /**
     *     「把記錄按步長 gap分組,對每組記錄採用直接插入排序方法進行排序。保證整個序列基本有序.」<br>
     * @param arr
     */
    public static void shellSort(int[] arr) {
        int size = arr.length;
        //把下標增量爲gap的記錄編爲一個子序列
        //增量逐步減少,直到整個序列的子序列爲自己,即增量gap=1
        for (int gap = size / 2; gap >= 1; gap /= 2) {
            //對子序列進行直接插入排序
            for (int i = gap; i < size; i++) {
                int key = arr[i];
                int j = i - gap;
                for (; j >= 0 && key < arr[j]; j -= gap) {
                    arr[j + gap] = arr[j];
                }
                arr[j + gap] = key;
            }
            System.out.println("gap: " + gap + " :" + Arrays.toString(arr));
        }
    }
相關文章
相關標籤/搜索