討厭算法的程序員 1 - 插入排序

討厭算法的程序員系列入口

什么是算法

在說插入排序之前,我們了解下《算法導論》對算法的從兩種不同角度的定義。

一般性解釋:

算法是定義良好的計算過程,它取一個或一組值作為輸入,并產生出一個或一組值作為輸出。

基于應用的解釋:

算法是一種工具,用來解決一個具有良好規格說明的計算問題。該問題的描述可以用通用的語言,來規定所需的輸入/輸出關系。與之對應的算法則描述了一個特定的計算過程,用于實現這一輸入/輸出關系。

后一種解釋在告訴我們,我們不必對于每個問題都去重新設計、證明和實現算法,而是有能力將實際問題轉換成已知算法問題,然后選取合適的解法。而這種能力就是學習算法的目的所在。這要求我們不僅要積累算法知識,還要在更高的抽象層次上理解算法的方法論。

排序問題的形式定義

排序問題是算法要解決的一個基本問題。它的形式化定義如下:

輸入:n個數的一個序列[a1, a2, ..., an]。

輸出:輸出序列的一個排列[a1', a2', ..., an'], 滿足a1' ≤ a2' ≤ ... ≤ an'。

插入排序算法

插入排序算法,對于少量元素的排序問題,是一個有效的算法。

經典應用

撲克

即便是玩過撲克牌的小孩子,其實都對插入排序算法了然于胸。

  • 摸牌之前,所有將會被你摸到的牌,此時是一種亂序的狀態。
  • 你開始摸牌,并將新摸到的牌插入到合適的位置,以保證你手中的牌總是有序的。
  • 直到摸到最后一張,將其插入到合適的位置,此時你手中所有的牌就已經排好序了。

算法的抽象表達

想讓計算機聽懂上述的算法,需要將其進行翻譯。

INSERTION-SORT(A)
1 for j = 2 to A.length
2   key = A[j]
3   // Insert A[j] into the sorted sequence A[1..j-1].
4   i = j - 1
5   while i > 0 and A[i] > key
6       A[i + 1] = A[i]
7       i = i - 1
8   A[i + 1] = key

原著中的偽碼無可挑剔,就沿用了。做一些說明:

  • 算法名稱INSERT-SORT;
  • A是一個長度為n的要排序的數組,用A.length表示n;
  • 把待排序數組A邏輯上分為兩個數組,排好序的(手中的牌),未排序的(桌上待摸的牌);
  • 排好序的數組起始只有一個元素,就是原數組A的第一個元素(摸出的第一張牌無需排序),循環變量用i表示;
  • 未排序的數組起始,從原數組A的第二個元素一直到最后一個元素,所以外層的遍歷是“2 to A.length”,循環變量用j表示;
  • 外層遍歷過程中,每個當前元素A[j]都暫存至key變量中;
  • key要加入排序好的數組,會從該排序好數組的最末i(j-1)開始進行比較,如果A[i]大于key,A[i]移動到A[i+1],i自減,繼續與key比較,如果此時i ≤ 0 或者 A[i] ≤ key,循環條件不成立跳出,將key存入A[i+1]。

算法工作例子

插入算法如何工作

說明:

  • (a)~(e)是循環迭代,(f)是最終排好的數組;
  • 數組上方是數組的下標;
  • 黑色塊表示每次外層迭代,待插入左側數組的數A[j];
  • 灰色塊表示參與和A[j]比較的數;
  • 黃色箭頭是偽碼第6行表達的移動;
  • 藍色大箭頭是偽碼第8行表達的移動;

Java實現

public class InsertionSort {
    public static void sortInASC(int[] numbers){
        for(int j = 1; j < numbers.length; j++){
            int key = numbers[j];
            int i = j - 1;
            while(i >= 0 && numbers[i] > key){
                numbers[i + 1] = numbers[i];
                i = i - 1;
            }
            numbers[i + 1] = key;
        }
    }
}

InsertSort.java下載

上一篇 0 前言
下一篇 2 證明算法的正確性


共享協議:署名-非商業性使用-禁止演繹(CC BY-NC-ND 3.0 CN)
轉載請注明:作者黑猿大叔(簡書)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容