1. 程式人生 > >通俗理解插入排序(直接插入排序,折半插入排序,希爾排序)

通俗理解插入排序(直接插入排序,折半插入排序,希爾排序)

直接插入排序

直接插入排序就是將待排序的值,逐一按元素的大小插入前面的有序序列
例如對-23,45,2,-45,9,5,3,65,-24進行直接插入排序,我們可以看成將45,2,-45,9,5,3,65,-24逐步插入-23的序列
這裡寫圖片描述

package sort;
public class Demo6 {
    public static void main(String[] args) {
        int[] num = new int[]{-23,45,2,-45,9,5,3,65,-24};
        sort(num);
        for (int i = 0
; i < num.length; i++) { System.out.print(num[i]+" "); } } public static void sort(int[] data){ int tmp;//暫時儲存待插入的值 //從第2個開始,進行n-1的插入操作 for (int i = 1; i < data.length; i++) { //若待插入的值比前面有序序列的最大值都大,則說明現在就是有序的 if(data[i]<data[i-1
]){ tmp = data[i]; int j = i-1; for (; j >=0&&data[j]>tmp; j--) { data[j+1] = data[j];//把資料往後移動 } data[j+1] = tmp;//退出迴圈時候,j指向的數值比tmp小,或者j<0 } } } }

這裡寫圖片描述

折半插入排序

折半插入排序是對直接插入排序的一種改進,直接插入排序中0到i-1有序的,折半插入排序就是用折半查詢迅速找到需要插入的地方,而不用從i-1開始逐一向前比較。

這裡寫圖片描述
使用折半查詢查詢3應該插入的位置,
1. low=0 hight=6 mid=(low+hight)/2=3
因為data[3]<=data[7],說明應該插入的位置在4-6之間
這裡寫圖片描述
2. low=mid+1=3+1=4 hight=6 mid=(low+hight)/2=5
這裡寫圖片描述
因為data[5]>data[7]說明應該插入的位置在4到5間

3 low=4 hight=mid-1=5 mid=(4+5)/2=4
這裡寫圖片描述
因為data[4]>data[7]所以插入的位置是4,但是此時折半查詢並沒有結束
4 low=4 hight=mid-1=3 因為此時low>hight所以折半折半查詢結束
這裡寫圖片描述
low的位置便是應該插入的位置(該位置滿足data[low]>待插入的值,data[hight]<=待插入的值,或者hight為-1,也就是插入的位置為0)
5 將low到i-1的數字都往後移動騰出low的位置將插入值插入,注意備份i位置的值避免被覆蓋後找不回待插入值。
這裡寫圖片描述

package sort;
public class Demo7 {
    public static void main(String[] args) {
        int[] data = new int[]{-23,45,2,-45,9,5,3,65,-24};
        sort(data);
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+" ");
        }
    }
    public static void sort(int[] data){
        int low,hight,mid;
        int tmp;//備份儲存待插入的值
        for (int i = 1; i < data.length; i++) {
            if(data[i]<data[i-1]){
                tmp = data[i];
                low = 0;
                hight = i-1;
                while(low<=hight){
                    mid = (low+hight)/2;
                    if(data[mid]<=tmp){  //當中間值小於等於待插入的值,搜尋[mid+1,hight]區間
                        low = mid +1;
                    }else{
                        hight = mid - 1; //當中間值小於等於待插入的值,搜尋[low,mid-1]區間
                    }
                }
                //將[low,i-1]區間的值後移動
                for (int j = i-1; j >= low; j--) {
                    data[j+1] = data[j];
                }
                //待插入的值插入
                data[low] =tmp;
            }
        }
    }
}

這裡寫圖片描述

希爾排序(Shell排序)

Shell排序是對直接插入排序的改進,它通過加大插入排序中元素之間的間隔,並在這些有間隔的元素進行插入排序,使得資料項跨度移動,不用一步一步往前比較和移動。
Shell排序演算法的關鍵就在於確定h序列的值,h就是間隔多少,序列最小值為1(這時就是直接插入排序),它們存在h=3*h+1的關係。當對一個數列進行Shell排序時,h的值為多少開始比較合適?h剛好大於數列長度除於3。

int h=1;
while(h<=arrayLength/3){
  h = 3*h+1;
}
//得到的h的值就是Shell排序的增量

得到了Shell排序的增量h序列值後,就從第h個後面數字開始對前面間隔h的值進行插入排序。
例如對-23,45,2,-45,9,5,3,65,-24進行Shell排序
1.長度為9,則可以計算出增量為4
2.從第4個後面數字(這裡就是9)開始對前面間隔4的值進行插入排序
這裡寫圖片描述

package sort;
public class Demo5 {
    public static void main(String[] args) {
        int[] num = new int[]{-23,45,2,-45,9,5,3,65,-24};
        sort(num);
    }
    public static void sort(int[] data){
        int h = 1;//增量最小為1
        int tmp;//儲存待插入的值
        while(h<=data.length/3){ //計算Shell的最大增量
            h = h * 3 + 1;
        }
        while(h>=1){
            //從第h後面的數字開始對前面的間隔為h的數字進行插入排序,也就是從第h+1個開始,下標為h
            for(int i = h; i<data.length; i++){
                tmp = data[i];
                if(data[i-h]>tmp){
                    int j = i-h;
                    //對前面的間隔為h的數字進行插入排序,,,當為1時就是直接插入排序了
                    for (; j>=0&&data[j]>tmp; j=j-h) {
                        data[j+h] = data[j];//資料往後移動,間隔為h
                    }
                    data[j+h] = tmp;//這裡加上h是因為迴圈最後還減多了一個h
                }
            }
            h = (h-1)/3;//重新計算h的值,尋找小一點的增量

            //打印出來看看,每一趟的Shell排序
            for (int j = 0; j < data.length; j++) {
                System.out.print(data[j]+" ");
            }
            System.out.println();
        }
    }
}

這裡寫圖片描述

三種插入排序的時間複雜度和空間複雜度

插入排序 時間複雜度 空間複雜度
直接插入排序 O(n^2) O(1)
折半插入排序 O(n^2) O(1)
希爾排序 O(n^3/2)~O(n^7/6) O(1)

相關推薦

簡單排序演算法時間空間複雜度分析及應用(7)-排序

希爾排序,屬於插入排序的一種,是直接插入排序的加強版。在希爾排序中引入了步長(gap)的概念,然而在插入排序中,步長預設為1。正如我們直接堆插入排序的分析,資料集合的排列順序對插入排序的效率會由很大的

通俗理解插入排序直接插入排序折半插入排序排序

直接插入排序 直接插入排序就是將待排序的值,逐一按元素的大小插入前面的有序序列 例如對-23,45,2,-45,9,5,3,65,-24進行直接插入排序,我們可以看成將45,2,-45,9,5,3,65,-24逐步插入-23的序列 package

【算法拾遺java描寫敘述】--- 插入排序直接插入排序排序

ecan itblog insert med image java程序 can rip title 插入排序基本思想 每次將一個待排序的記錄按其keyword大小插入到前面已經拍好序的子文件的適當位置,直到全部記錄插入完畢為止。 直接插入

數據結構四十四插入排序1.直接插入排序 2.排序

結束 縮小 移動 個數 數據 空間 分析 過程 只有一個   一、插入排序的基本思想   從初始有序的子集合開始,不斷地把新的數據元素插入到已排列有序子集合的合適位置上,使子集合中數據元素的個數不斷增多,當子集合等於集合時,插入排序算法結束。常用的 插入排序算法有直接插入排

排序演算法之插入排序直接插入排序

前言 一個好的排序演算法對於程式的優化會有很大的提升,雖然在許多語言的類庫中就存在了N種排序方法,但是隻有在瞭解了每一種排序演算法後才能更好的在實際中運用這些演算法。這裡我主要說明插入排序中的直接插入以及希爾排序的實現。 直接插入 直接插入排序是最簡單的排序演算法之一。對於直

排序演算法直接插入、氣泡排序、選擇排序、快速排序排序、堆排序、歸併排序

main函式 int main() { int data[] = {1,2,6,3,4,7,7,9,8,5}; //bubble_sort(data,10); //select_sort(data,10); Insert_Sort(data,10); fo

插入排序直接插入排序&折半插入排序&排序

目錄 1,插入排序 概念:插入排序的基本方法:每一步將一個待排序元素按照其排序碼的大小,插入到前面已經排好序的一組元素的適當位置,直到元素全部插入為止。 1.1,直接插入排序 演算法思想:直接插入排序是原地排序,把陣列中的a[n]中的n個元素看

排序演算法--插入直接插入二分插入

一、插入類排序 1.直接插入排序 演算法思想:基本操作是將第i個記錄插入到前面第i-1個已排序好的記錄中。具體過程:把第i個記錄的關鍵字Ki,依次與前面Ki-1,Ki-1,...,K1比較,將所有關鍵字大於Ki的記錄依次先後移動一個位置,直到遇到一個關鍵字Kj小於或等於關

優化的直接插入排序二分查詢插入排序排序

   本博文向大家介紹了插入排序的三種實現:直接插入排序,二分查詢插入排序,希爾排序。詳細分析的其實現過程、時間複雜度和空間複雜度、穩定性以及優化改進策略。最後簡單的做了下效能測試。 直接插入排序 (一)概念及實現 直接插入排序的原理:先將原序列分為有序區和無序區,然後再經過比較和後移操作將無序

排序演算法氣泡排序簡單選擇排序直接插入排序排序

氣泡排序,簡單選擇排序,直接插入排序是三種複雜度為O(n2)的演算法,希爾排序在特殊增量序列的時候可以獲得複雜度為O(n3/2) 氣泡排序 1、最簡單的排序實現 這裡把每個數和這個數之後的每個數比較,大於就交換位置。 缺點:多出了很多次沒有用的交

交換排序氣泡排序~快速排序~+插入排序直接插入排序~排序~

一、氣泡排序 1、基本概念 依次比較相鄰的兩個數,將小數放在前面,大數放在後面。 第一趟:首先比較第1個數和第2個數,將小數放前,大數放後;然後比較第2個數和第3個數,將小數放前,大數放後;如此繼續,直至比較最後兩個數,將小數放前,大數放後;至此第一趟結束,使得最後一個數字是最大的了!

資料結構之排序演算法-直接插入排序排序直接選擇排序

直接插入排序:時間複雜度:O(n^2) 基本演算法思路是:把後面待排序的記錄按其關鍵字的大小逐個插入到一個已經排好序的有序序列中,直到所有記錄插完為止,得到一個新的有序序列。(無序插入前面有序) 演算

學生成績排序直接插入冒泡快排選擇堆排2路歸併

內容: 給出n個學生的考試成績表,每條記錄由學號、姓名和分數和名次組成,設計演算法完成下列操作: (1)設計一個顯示對學生資訊操作的選單函式如下所示: *************************        1、錄入學生基本資訊        2、直接插入排序  

java排序直接插入排序

1.直接插入排序 基本思想: 在排序的一組數中,假設前面(n-1)比n大,則把n和(n-1)換一下位置。如果(n+2)比n小,則把(n+2)放在n前面,n後面的數依次後移一位。 例項圖: java實現: public class insertSort{ public i

演算法---插入排序直接插入排序

插入排序:其基本操作就是將一個數據插入到已經拍好序的有序資料中,從而得到一個新的、個數加一 的有序資料,演算法適用於少量資料的排序。 包括:直接插入排序,二分插入排序(又稱折半插入排序),連結串列插入

資料結構-插入排序直接插入排序+折半插入排序

二、插入排序 1.直接插入排序 這裡我們注意,元素的選擇是從第二個元素開始!動態過程如下: 遞增的程式碼實現: #include<iostream> using namesp

八大排序:四種簡單的排序直接插入排序排序、氣泡排序、選擇排序

一、直接插入排序 直接插入排序基本思想是每一步將一個待排序的記錄,插入到前面已經排好序的有序序列中去,直到插完所有元素為止。 直接插入排序演算法的運作如下: 假設有一組無序序列 R0, R1, … , RN-1。 (1) 我們先將這個序列中下標為 0

插入排序算法之直接插入排序排序

.cn 一定的 思路 value urn ges 高效 代碼 面向 插入排序算法 有一個已經有序的數據序列,要求在這個已經排好的數據序列中插入一個數,但要求插入後此數據序列仍然有序,這個時候就要用到一種新的排序方法——插入排序法,插入排序的基本操作就是將一個數據插入到已經排

排序插入排序直接插入排序

insert void shel body 位置 由於 temp 不同 bsp 一、插入排序 1、思想:原理類似抓撲克牌,在有序表中進行插入和查找,插入合適的位置時,之後的元素需要往後移動 2、時間復雜度: 最好:O(N),正序情況,只有比較時間,無移動時間 最壞:O(N2

插入排序_排序python

code 使用 color emp def 希爾 pytho and div 希爾排序首先選擇增量,對原列表分組,然後將同組數組使用直接插入法排序,最後增量為1,實現全局排序 1 ‘‘‘ 2 希爾排序 3 空間復雜度O(1) 4 時間復雜度最壞(pow(n,2))