插入排序就這么簡(jiǎn)單

插入排序就這么簡(jiǎn)單

從上面已經(jīng)講解了冒泡和選擇排序了,本章主要講解的是插入排序谅辣,希望大家看完能夠理解并手寫(xiě)出插入排序的代碼沧竟,然后就通過(guò)面試了!如果我寫(xiě)得有錯(cuò)誤的地方也請(qǐng)大家在評(píng)論下指出带污。

插入排序介紹

來(lái)源百度百科:

插入排序的基本操作就是將一個(gè)數(shù)據(jù)插入到已經(jīng)排好序的有序數(shù)據(jù)中,從而得到一個(gè)新的香到、個(gè)數(shù)加一的有序數(shù)據(jù)鱼冀,算法適用于少量數(shù)據(jù)的排序,時(shí)間復(fù)雜度為O(n^2)悠就。是穩(wěn)定的排序方法千绪。

將一個(gè)數(shù)據(jù)插入到已經(jīng)排好序的有序數(shù)據(jù)

  • 將要排序的是一個(gè)亂的數(shù)組int[] arrays = {3, 2, 1, 3, 3};
  • 在未知道數(shù)組元素的情況下,我們只能把數(shù)組的第一個(gè)元素作為已經(jīng)排好序的有序數(shù)據(jù)梗脾,也就是說(shuō)荸型,把{3}看成是已經(jīng)排好序的有序數(shù)據(jù)

一、第一趟排序

用數(shù)組的第二個(gè)數(shù)與第一個(gè)數(shù)(看成是已有序的數(shù)據(jù))比較

  • 如果比第一個(gè)數(shù)大炸茧,那就不管他
  • 如果比第一個(gè)數(shù)小瑞妇,將第一個(gè)數(shù)往后退一步鹉究,將第二個(gè)數(shù)插入第一個(gè)數(shù)去

    int temp;
    if (arrays[1] > arrays[0]) {
        //如果第二個(gè)數(shù)比第一個(gè)數(shù)大,直接跟上

    } else {
        //如果第二個(gè)數(shù)比第一個(gè)數(shù)小踪宠,將第一個(gè)數(shù)后退一個(gè)位置(將第二個(gè)數(shù)插進(jìn)去)
        temp = arrays[1];
        arrays[1] = arrays[0];
        arrays[0] = temp;

    }

    System.out.println("公眾號(hào)Java3y" + arrays);
image

二、第二趟排序

用數(shù)組的第三個(gè)數(shù)與已是有序的數(shù)據(jù){2,3}(剛才在第一趟排的)比較

  • 如果比2大妈嘹,那就不管它
  • 如果比2小柳琢,那就將2退一個(gè)位置,讓第三個(gè)數(shù)和1比較
    • 如果第三個(gè)數(shù)比1大润脸,那么將第三個(gè)數(shù)插入到2的位置上
    • 如果第三個(gè)數(shù)比1小柬脸,那么將1后退一步,將第三個(gè)數(shù)插入到1的位置上

    //第二趟排序--------------------

    if (arrays[2] > arrays[1]) {
        //如果第三個(gè)數(shù)比第二個(gè)數(shù)大毙驯,直接跟上

    } else {
        //如果第三個(gè)數(shù)比第二個(gè)數(shù)小倒堕,將第二個(gè)數(shù)往后退一個(gè)位置,讓第三個(gè)數(shù)跟第一個(gè)數(shù)比
        temp = arrays[2];
        arrays[2] = arrays[1];

        //如果第三個(gè)數(shù)比第一個(gè)大爆价,那就插入到第二個(gè)數(shù)中
        if (temp > arrays[0]) {
            arrays[1] = temp;
        } else {

            //如果第三個(gè)數(shù)比第一個(gè)小垦巴,將第三個(gè)數(shù)插入到第一個(gè)數(shù)前面
            int swapTemp = arrays[0];
            arrays[0] = temp;
            arrays[1] = swapTemp;

        }

    }
    System.out.println("公眾號(hào)Java3y" + arrays);
image

....

三、簡(jiǎn)化代碼

從前兩趟排序我們可以摸出的規(guī)律:

  • 首先將已排序的數(shù)據(jù)看成一個(gè)整體
  • 一個(gè)數(shù)組是需要n-1趟排序的铭段,總是用后一位跟已排序的數(shù)據(jù)比較(第一趟:第二位跟已排序的數(shù)據(jù)比骤宣,第二趟:第三位跟已排序的數(shù)據(jù)比)
  • 用第三位和已排序的數(shù)據(jù)比,實(shí)際上就是讓第三位數(shù)跟兩個(gè)數(shù)比較序愚,只不過(guò)這兩個(gè)數(shù)是已經(jīng)排好序的而已憔披。而正是因?yàn)樗藕眯虻模覀兛梢?strong>使用一個(gè)循環(huán)就可以將我們比較的數(shù)據(jù)插入進(jìn)去

    //臨時(shí)變量
    int temp;

    //外層循環(huán)控制需要排序的趟數(shù)(從1開(kāi)始因?yàn)閷⒌?位看成了有序數(shù)據(jù))
    for (int i = 1; i < arrays.length; i++) {

        temp = arrays[i];

        //如果前一位(已排序的數(shù)據(jù))比當(dāng)前數(shù)據(jù)要大爸吮,那么就進(jìn)入循環(huán)比較[參考第二趟排序]
        while (arrays[i - 1] > temp) {

            //往后退一個(gè)位置芬膝,讓當(dāng)前數(shù)據(jù)與之前前位進(jìn)行比較
            arrays[i] = arrays[i - 1];

            //不斷往前,直到退出循環(huán)
            i--;

        }

        //退出了循環(huán)說(shuō)明找到了合適的位置了形娇,將當(dāng)前數(shù)據(jù)插入合適的位置中
        arrays[i] = temp;

    }

上面的代碼還缺少了一個(gè)條件:如果當(dāng)前比較的數(shù)據(jù)比已排序的數(shù)據(jù)都要小锰霜,那么while中的arrays[i - 1]會(huì)比0還要小,這會(huì)報(bào)錯(cuò)的桐早。


Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
    at Main.main(Main.java:61)

我們應(yīng)該加上一個(gè)條件:i>=1時(shí)才可以锈遥,如果i=1了下次再進(jìn)去的時(shí)候就退出循環(huán),讓當(dāng)前數(shù)據(jù)插入到[0]的位置上

所以完整的代碼是這樣的:


     //臨時(shí)變量
        int temp;

        //外層循環(huán)控制需要排序的趟數(shù)(從1開(kāi)始因?yàn)閷⒌?位看成了有序數(shù)據(jù))
        for (int i = 1; i < arrays.length; i++) {

            temp = arrays[i];

            //如果前一位(已排序的數(shù)據(jù))比當(dāng)前數(shù)據(jù)要大勘畔,那么就進(jìn)入循環(huán)比較[參考第二趟排序]
            while (i >= 1 && arrays[i - 1] > temp) {

                //往后退一個(gè)位置所灸,讓當(dāng)前數(shù)據(jù)與之前前位進(jìn)行比較
                arrays[i] = arrays[i - 1];

                //不斷往前,直到退出循環(huán)
                i--;

            }

            //退出了循環(huán)說(shuō)明找到了合適的位置了炫七,將當(dāng)前數(shù)據(jù)插入合適的位置中
            arrays[i] = temp;

        }
        System.out.println("公眾號(hào)Java3y" + arrays);
image

四爬立、插入排序優(yōu)化

二分查找插入排序的原理:是直接插入排序的一個(gè)變種,區(qū)別是:在有序區(qū)中查找新元素插入位置時(shí)万哪,為了減少元素比較次數(shù)提高效率侠驯,采用二分查找算法進(jìn)行插入位置的確定抡秆。

參考資料:http://www.cnblogs.com/heyuquan/p/insert-sort.html

五、擴(kuò)展閱讀

C語(yǔ)言實(shí)現(xiàn)第一種方式:


        void InsertSortArray ( int arr[], int n)
        {

            //int arr[]={2,99,3,1,22,88,7,77,54};
            for (int i = 1; i < n; i++)// 循環(huán)從第二個(gè)數(shù)組元素開(kāi)始
            {
                int temp = arr[i];//temp標(biāo)記為未排序的第一個(gè)元素
                while (i >= 0 && arr[i - 1] > temp) //將temp與已排序元素從大到小比較吟策,尋找temp應(yīng)插入的元素
                {
                    arr[i] = arr[i - 1];
                    i--;
                }
                arr[i] = temp;
            }

        }

C語(yǔ)言實(shí)現(xiàn)第二種方式:


        void insert ( int arr[], int n)
        {
            int key = arr[n];
            int i = n;
            while (arr[i - 1] > key) {
                arr[i] = arr[i - 1];
                i--;
                if (i == 0)
                    break;
            }
            arr[i] = key;
        }

        void insertionSort ( int arr[], int n)
        {
            int i;
            for (i = 1; i < n; i++) {
                insert(arr, i);
            }
        }

測(cè)試代碼:


  main()
        {
            int arr[] = {99, 2, 3, 1, 22, 88, 7, 77, 54};
            int i;
            insertionSort(arr, 9);
            for (int i = 0; i < 9; i++)
                cout << arr[i] << endl;
            return 0;
        }

參考資料:

如果文章有錯(cuò)的地方歡迎指正儒士,大家互相交流。習(xí)慣在微信看技術(shù)文章檩坚,想要獲取更多的Java資源的同學(xué)着撩,可以關(guān)注微信公眾號(hào):Java3y

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市匾委,隨后出現(xiàn)的幾起案子拖叙,更是在濱河造成了極大的恐慌,老刑警劉巖赂乐,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件薯鳍,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡挨措,警方通過(guò)查閱死者的電腦和手機(jī)挖滤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)浅役,“玉大人壶辜,你說(shuō)我怎么就攤上這事〉W猓” “怎么了砸民?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)奋救。 經(jīng)常有香客問(wèn)我岭参,道長(zhǎng),這世上最難降的妖魔是什么尝艘? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任演侯,我火速辦了婚禮,結(jié)果婚禮上背亥,老公的妹妹穿的比我還像新娘秒际。我一直安慰自己,他們只是感情好狡汉,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布娄徊。 她就那樣靜靜地躺著,像睡著了一般盾戴。 火紅的嫁衣襯著肌膚如雪寄锐。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音橄仆,去河邊找鬼剩膘。 笑死,一個(gè)胖子當(dāng)著我的面吹牛盆顾,可吹牛的內(nèi)容都是我干的怠褐。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼您宪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼奈懒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蚕涤,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铣猩,沒(méi)想到半個(gè)月后揖铜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡达皿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年天吓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峦椰。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡龄寞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汤功,到底是詐尸還是另有隱情物邑,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布滔金,位于F島的核電站色解,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏餐茵。R本人自食惡果不足惜科阎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望忿族。 院中可真熱鬧锣笨,春花似錦、人聲如沸道批。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)隆豹。三九已至走趋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背簿煌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工氮唯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姨伟。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓惩琉,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親夺荒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瞒渠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 排序的基本概念 在計(jì)算機(jī)程序開(kāi)發(fā)過(guò)程中,經(jīng)常需要一組數(shù)據(jù)元素(或記錄)按某個(gè)關(guān)鍵字進(jìn)行排序技扼,排序完成的序列可用于快...
    Jack921閱讀 1,418評(píng)論 1 4
  • 概述:排序有內(nèi)部排序和外部排序伍玖,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大剿吻,一次不能容納全部...
    每天刷兩次牙閱讀 3,727評(píng)論 0 15
  • 概述 排序有內(nèi)部排序和外部排序窍箍,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大丽旅,一次不能容納全部...
    蟻前閱讀 5,164評(píng)論 0 52
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個(gè)記錄插入到已排序好...
    依依玖玥閱讀 1,239評(píng)論 0 2
  • 小時(shí)候椰棘,總想著長(zhǎng)大了要去遠(yuǎn)方,不知不覺(jué)間榄笙,我們已經(jīng)身處在遠(yuǎn)方了邪狞。也許你也會(huì)有這樣的時(shí)刻:有時(shí),特別想特別想去做一件...
    蔣小丫閱讀 336評(píng)論 1 3