數據結構->排序->插入排序


排序->內部排序->插入排序

1.直接插入排序

算法思想

​ 每次將一個待排序的記錄按照關鍵字大小插入已排好序的子序列,直到全部記錄插入完成。

實現思路(順序:非遞減有序序列)

		1. 記錄當前需要排序元素的位置與大小(設位置為 i,大小為min )
		2. 以 i 為分界線,其前為一個有序序列,其后為待排序元素
		3. 將 min 與有序序列中的元素進行比較,直到該元素 <= min,否則將該元素后移。
		4. 將 min 元素放入有序列表
		5. 循環(i++),直到有序

實現代碼

點擊查看代碼
/**
     * 插入排序,最普通的實現方法(還有一種帶哨兵的實現方法,就不在此實現了)
     * @param arr
     */
public static void InsertSort(int[] arr){
    for(int i = 1; i < arr.length; i++){
        // 1. 當前需要排列的元素
        int value = arr[i];
        int j;
        // 2. 以當前下標為分界線,前為有序,找到比他更小的元素
        for(j = i-1; j >= 0; j--){
            if(arr[j] <= value){
                break ;
            }
            // 將比它大的元素后移
            arr[j+1] = arr[j];
        }
        // 3. 將元素放在他應在的位置上
        arr[j+1] = value;
    }
}

2.折半插入排序

算法思想

​ 在直接插入的基礎上,可以尋找元素在有序表中的位置時使用折半查找的方法,能夠減少時間復雜度。

算法思路

​ 同上,但在進行 3 時使用折半查找的方法。

實現代碼

點擊查看代碼
/**
     * 折半插入排序
     *      插入排序的一種優化,同樣還有一種帶哨兵的實現方法,不再次實現了。
     * @param arr
     */
public static void InsertSortBin(int[] arr){
    for(int i = 1; i < arr.length; i++){
        int value = arr[i];
        int left = 0;
        int right = i-1;
        int mid;
        // 折半查找元素應該在的位置
        while (left <= right){
            mid = (left+right)/2;
            if(arr[mid] <= value){
                left = mid+1;
            }else {
                right = mid-1;
            }
        }

        // 將該位置之后的元素后移
        for(int j = i-1; j >= right+1; j--){
            arr[j+1] = arr[j];
        }
        arr[right+1] = value;
    }
}

3.希爾排序

算法思想

​ 把待排序表分成若干個等長間隔的子表,對每個子表分別進行插入排序,當整個表中的元素都基本有序時,再對全體記錄進行一次直接插入排序。

算法思路

​ 1.取一個小於n的步長d1,將表中的元素分為d1組,所以距離為d1的元素放在一個組里;

​ 2.組內進行直接插入排序;

​ 3.取第二個步長d2 < d1,重復上述過程,直到dt = 1,再進行直接插入排序。

​ ps: 到目前為止,還沒有得出最優的增量序列(步長序列),希爾提出的方法是每次折半,即d1 = n/2; d2 = d1/ 2,......直到最后增量等於1。

實現代碼

點擊查看代碼
/**
     * 希爾排序
     *  第一個結點暫存元素,不參與排序
     * @param arr
     */
public static void ShellSort(int[] arr){
    for(int d = arr.length/2; d >= 1; d /= 2){
        for(int i = d+1; i < arr.length; i++){
            if(arr[i] < arr[i-d]){
                arr[0] = arr[i];
                int j;
                for(j = i-d; j > 0 && arr[0] < arr[j]; j -= d){
                    arr[j+d] = arr[j];
                }
                arr[j+d] = arr[0];
            }
        }
    }
}

4.其他結論

直接插入排序最壞情況下需要進行的比較次數為:n*(n-1)/2;

直接插入排序屬於穩定排序,而希爾排序屬於不穩定排序;

直接插入的三種排序方法時間復雜度都為O(n^2);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM