算法入門教程-插入排序

上節(jié)我們學習了選擇排序算法,本節(jié)我們繼續(xù)學習相關剩余算法如我們本節(jié)要學習的插入排序,直接入正題,先來介紹下什么是插入排序?

插入排序介紹

插入排序也是基于內存操作的,是對想要排序的元素已插入的方式尋找到該元素的位置已達到排序的效果.

看著很難以理解,通過一個例子來看看,如圖:

插入排序圖.png

上圖中初始狀態(tài)我們可以看成是一個數組R,其中R[0]~R[5]表示對應值的下標索引,其中該數組為R= {17,3,25,14,20,9},接著我們來看一下這個過程

  • 說明:
  • 1 我們可以將R數組看成是一個有序列列{17}和無序列{3,25,14,20,9},我們要做到是將.
  • 無序列中的值往有序列{17}中插入,至于規(guī)則自己定.'
  • 2 我這里就按照上圖中的來說插入的時候按照從小到大插入即可
  • 過程:
  • 第一次插入的時候,將無序列中的下標為1的值(3)插入有序列中{17}中,發(fā)現要插入的值小于有序列中的原先的值,首先將原先有序列中的值往后移動一位,接著將3插入空出來的位置即可.
  • 第二次插入的時候是將數組R中的R[2]也就是值為25,通過判斷發(fā)現25大于有序列中的3和17,故它的位置不變,這里是一種巧合的場景.
  • 第三次插入的時候,將數組R中的R[3]插入到有序列表{3,17,25}中通過比較14大于3小于17即插入到3和17之間即可
  • 第四次和第五次重復上述過程即可

這就是上圖中插入排序的過程,通過上圖的過程我們來總結下插入排序的思想:

  • 按照上述過程得到,我們可以將一個待排序的元素看成是一個有序列表和無序列表.
  • 首先開始的時候有序列表中只有一個元素(所以它一定是有序的),無序列表中有n-1個元素
  • 在排序的過程中,每次從無序列表中取出第一個元素,把它的排序號依次跟有序列表中的進行比較,然后將它插入到有序列表中的適當位置,使之成為新的有序列表.

知道了它的排序思想,我們通過代碼來完成該過程

代碼實現

假設我這里有一個待排序的數組元素集合arr={101,34,119,1},需要進行排序,我們來看過程

  • 第一次的排序代碼實現
//逐步推導過程
    //{101,34,119,1} -> 首先以{101}為有序列表,以{4,119,1}為無序列表
    //將無序列表中的數往有序列表中添加
    //定義待插入的數和索引下標
    int insertVal = arr[1]; //這里也就是34
    int insertIndex = 1 - 1; //arr[1]前面數的下標

    //簡單說明:
    //1. insertIndex>=0 其主要的目的是為了防止在插入時候為了約束越界
    //2. insertVal < arr[insertIndex]表示待插入的數還沒有找到插入的位置如: 34 < arr[0] =101
    //3. 需要將 arr[insertIndex]往后移動
    while (insertIndex >= 0 && insertVal < arr[insertIndex]) {

        arr[insertIndex + 1] = arr[insertIndex]; //此時的數組為{101,101,119,1}
        insertIndex--;
    }
    //當退出while循環(huán)時,說明插入的位置找到,需要 insertIndex +1 如: 34改為 134
        arr[insertIndex + 1] = insertVal;
    System.out.println("第一輪插入后的結果為:");
    System.out.println(Arrays.toString(arr));

我們先來猜測下結果,我猜測第一次排序過后的數組為{34,101,119,1},多說無益,來看測試結果:

插入排序第一輪結果圖.png

從上述結果來看我們的猜測是正確的,接著看

  • 第二次的排序過程:
   //定義待插入的數和索引下標
     insertVal = arr[2]; //這里也就是119
     insertIndex = 2-1; //arr[2]前面數的下標
    //簡單說明:
    //1. insertIndex>=0 其主要的目的是為了防止在插入時候為了約束越界
    //2. insertVal < arr[insertIndex]表示待插入的數還沒有找到插入的位置如: 34 < arr[] =101
    //3. 需要將 arr[insertIndex]往后移動
    while (insertIndex >=0 && insertVal < arr[insertIndex]){

        arr[insertIndex +1] = arr[insertIndex]; //此時的數組為{101,101,119,1}
        insertIndex --;
    }
    //當退出while循環(huán)時,說明插入的位置找到,需要 insertIndex +1 如: 34改為 134
    arr[insertIndex + 1] = insertVal;
    System.out.println("第二輪插入后的結果為:");
    System.out.println(Arrays.toString(arr));

不猜了,直接看結果圖:

第二輪結果圖.png

-第三次過程:

//定義待插入的數和索引下標
    insertVal = arr[3]; //這里也就是119
    insertIndex = 3-1; //arr[2]前面數的下標
    //簡單說明:
    //1. insertIndex>=0 其主要的目的是為了防止在插入時候為了約束越界
    //2. insertVal < arr[insertIndex]表示待插入的數還沒有找到插入的位置如: 34 < arr[] =101
    //3. 需要將 arr[insertIndex]往后移動
    while (insertIndex >=0 && insertVal < arr[insertIndex]){

        arr[insertIndex +1] = arr[insertIndex]; //此時的數組為{101,101,119,1}
        insertIndex --;
    }
    //當退出while循環(huán)時,說明插入的位置找到,需要 insertIndex +1 如: 34改為 134
    arr[insertIndex + 1] = insertVal;
    System.out.println("第三輪插入后的結果為:");
    System.out.println(Arrays.toString(arr));

來看測試結果:

第三輪測試結果圖.png

通過上述過程我們完成了該元素的排序過程,我們來封裝下代碼:

//插入排序方法封裝
public static void insertSort(int [] arr){
        int insertVal = 0;
        int insertIndex = 0;
    for (int i = 1; i <arr.length; i++) {
        //逐步推導過程
        //{101,34,119,1} -> 首先以{101}為有序列表,以{4,119,1}為無序列表
        //將無序列表中的數往有序列表中添加
        //定義待插入的數和索引下標
         insertVal = arr[i]; //這里也就是34
         insertIndex = i - 1; //arr[1]前面數的下標

        //簡單說明:
        //1. insertIndex>=0 其主要的目的是為了防止在插入時候為了約束越界
        //2. insertVal < arr[insertIndex]表示待插入的數還沒有找到插入的位置如: 34 < arr[0] =101
        //3. 需要將 arr[insertIndex]往后移動
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {

            arr[insertIndex + 1] = arr[insertIndex]; //此時的數組為{101,101,119,1}
            insertIndex--;
        }
        //當退出while循環(huán)時,說明插入的位置找到,需要 insertIndex +1 如: 34改為 134

        if (insertIndex +1 != i) {
            arr[insertIndex + 1] = insertVal;
        }
        System.out.println("第"+(i)+"輪插入后的結果為:");
        System.out.println(Arrays.toString(arr));
    }

最后一步我們來測試插入排序執(zhí)行10w數據的執(zhí)行時間,來看代碼:

/**
 * 算法學習-插入排序
 */
public class InsertSort {
public static void main(String[] args) {

    //int [] arr = {101,34,119,1};
    //insertSort(arr);
    //插入的時間復雜度測試
    int [] arr = new int[100000];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = (int)(Math.random() * 100000); //隨機生成[0,100000)的數
    }

    Date date1 = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String format = dateFormat.format(date1);
    System.out.println("排序前的時間為:"+format);
    //進行排序
    insertSort(arr);
    Date date2 = new Date();
    SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String format2 = dateFormat.format(date2);
    System.out.println("排序后的時間為:"+format2);

}

來看測試結果圖:

執(zhí)行時間測試結果圖.png

多次執(zhí)行,發(fā)現10w數據插入排序算法只需要1s,當然可能跟計算機CPU有關系,我們發(fā)現插入排序執(zhí)行的效率要高于選擇排序和冒泡排序算法,那么關于插入排序的學習就到這里

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末侯勉,一起剝皮案震驚了整個濱河市稻轨,隨后出現的幾起案子毫玖,更是在濱河造成了極大的恐慌厉熟,老刑警劉巖绍移,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件环凿,死亡現場離奇詭異,居然都是意外死亡萝挤,警方通過查閱死者的電腦和手機御毅,發(fā)現死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怜珍,“玉大人端蛆,你說我怎么就攤上這事∷址海” “怎么了今豆?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵嫌拣,是天一觀的道長。 經常有香客問我呆躲,道長异逐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任插掂,我火速辦了婚禮灰瞻,結果婚禮上,老公的妹妹穿的比我還像新娘辅甥。我一直安慰自己酝润,他們只是感情好,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布璃弄。 她就那樣靜靜地躺著要销,像睡著了一般。 火紅的嫁衣襯著肌膚如雪夏块。 梳的紋絲不亂的頭發(fā)上蕉陋,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音拨扶,去河邊找鬼。 笑死茁肠,一個胖子當著我的面吹牛患民,可吹牛的內容都是我干的。 我是一名探鬼主播垦梆,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼匹颤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了托猩?” 一聲冷哼從身側響起印蓖,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎京腥,沒想到半個月后赦肃,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡公浪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年他宛,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欠气。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡厅各,死狀恐怖,靈堂內的尸體忽然破棺而出预柒,到底是詐尸還是另有隱情队塘,我是刑警寧澤袁梗,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站憔古,受9級特大地震影響遮怜,放射性物質發(fā)生泄漏。R本人自食惡果不足惜投放,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一奈泪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧灸芳,春花似錦涝桅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谒获,卻和暖如春蛤肌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背批狱。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工裸准, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赔硫。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓炒俱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親爪膊。 傳聞我的和親對象是個殘疾皇子权悟,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容

  • 概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序推盛,而外部排序是因排序的數據很大峦阁,一次不能容納全部...
    蟻前閱讀 5,167評論 0 52
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個記錄插入到已排序好...
    依依玖玥閱讀 1,239評論 0 2
  • 概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序耘成,而外部排序是因排序的數據很大榔昔,一次不能容納全部...
    zwb_jianshu閱讀 1,105評論 0 0
  • 概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序瘪菌,而外部排序是因排序的數據很大件豌,一次不能容納全部...
    閑云清煙閱讀 756評論 0 6
  • 一、概述 排序算法概念 在計算機科學與數學中控嗜,一個排序算法是將一組雜亂無章的數據按一定的規(guī)律順次排列起來的算法茧彤。排...
    簡書冷雨閱讀 1,019評論 0 0