排序算法入門之「插入排序」

插入排序

借用《算法導論》裏的例子,就是咱們打牌的時候,每新拿一張牌都會把它按順序插入,這,其實就是插入排序。java

齊姐聲明:雖然咱們用打牌的例子,可是可不能學胡適先生啊。git

對於數組來講怎麼作呢?github

有一個重要的思想,叫作擋板法,就是用擋板把數組分紅兩個區間:算法

  • 擋板左邊:已排序
  • 擋板右邊:未排序

那麼排序分三步走:數組

  1. 最初擋板是在數組的最左邊,index = 0 的位置,也就是保證了已排序區間裏一個數都沒有,或者也能夠包含一個數啦;
  2. 核心思想就是:
    依次遍歷未排序區間裏的元素,在已排序區間裏找到正確的位置插入;
  3. 重複這個過程,直到未排序區間爲空。

舉個例子:{5, 2, 1, 0}

第一步,擋板最初在這裏:學習

第二步,
把 2 插入已排序區間的正確位置,變成:優化

重複這個步驟,把 1 排好:動畫

最後把 0 排好:spa

那代碼也很簡單:.net

public void insertionSort(int[] input) {
    if (input.length <= 1) {
        return;
    }
    for(int i = 1; i < input.length; i++) {
        int tmp = input[i];
        int j = i - 1;
        while(j >= 0 && input[j] > tmp) {
            input[j+1] = input[j];
            j --;
        }
        input[j+1] = tmp;
    }
}

咱們來分析一下這個算法的時空複雜度。

時間複雜度

關於時間複雜度有兩個要點

  • 是描述隨着自變量的增加,所需時間的增加率;
  • 是漸近線複雜度,就是說

    • 不看係數
    • 只看最高階項

那麼咱們關心的 worst case 的狀況就是:
若是數組是近乎倒序的,每次插入都要在數組的第一個位置插入,那麼已排序區間內的全部的元素都要日後移動一位,這一步平均是 O(n),那麼重複 n 次就是 O(n^2).

空間複雜度

重點是一個峯值的概念,並非累計使用的空間。
這裏是 O(1) 沒什麼好說的。

引入一個概念:sorted in place,也就是原地排序

原地排序就是指空間複雜度爲 O(1) 的算法,由於沒有佔用額外的空間,就是原地打轉嘛。

其實 in-place 的思想並非只在排序算法裏有,只不過排序算法是一個最廣爲人知的例子罷了。本質上就是一個節省使用空間的思想。

可是對於排序算法,只分析它的時空複雜度是不夠的,還有另一個重要指標:

穩定性

這個是排序算法的一個重要指標,意思是元素之間的相對順序是否保持了不變。

好比說:{5, 2, 2, 1, 0}

這個數組排序完成後這裏面的兩個 2 的相對順序沒有變,那麼這個排序就是一個穩定排序。

那有同窗可能就想,順序變了又有什麼關係呢?

其實,在實際工做中咱們排序的對象不會只是一個數字,而是一個個的對象 (object),那麼先按照對象的一個性質來排序,再按照另外一個性質來排序,那就不但願原來的那個順序被改變了。好像有點抽象,咱們舉個例子。

好比在股票交易系統裏,有買賣雙方的報價,那是如何匹配的呢?

  • 先按照價格排序;
  • 在相等的價格中,按照出價的時間順序來排序。

那麼一搬來講系統會維持一個按時間排序的價格序列,那麼此時只須要用一個具備穩定性的排序算法,再按照價格大小來排序就行了。由於穩定性的排序算法能夠保持大小相同的兩個對象仍維持着原來的時間順序。

那麼插入排序是不是穩定性的排序呢?答案是確定的。由於在咱們插入新元素的時候是從後往前檢查,並非像打牌的時候隨便插一個位置不能保證相對順序。

你們能夠看下下面的動畫 就很是清楚了~

優化

插入排序實際上是有很大的優化空間的,你能夠搜一下「希爾排序」。

在剛開始學習的時候,深度當然重要,但由於廣度不夠,若是學的太深可能會很痛苦,一個知識點就無窮無盡的延展,這並非一個高效的學習方式。

因此若是時間有限,就要作好深度和廣度的平衡:

  • 在經常使用常考的知識點上多花時間精力,追求深度;
  • 在一些拓展性的知識點上點到爲止,先知道有這麼回事就行。

保持 open minded 的心態,後期就會有質的提升。

若是你喜歡這篇文章,記得給我點贊留言哦~大家的支持和承認,就是我創做的最大動力,咱們下篇文章見!

我是小齊,紐約程序媛,終生學習者,天天晚上 9 點,雲自習室裏不見不散!

更多幹貨文章見個人 Github: https://github.com/xiaoqi6666...

相關文章
相關標籤/搜索