【一起學習排序演算法】4 插入排序
先看看Wikipedia的定義:
Insertion sort algorithm iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain.
所以插入排序的思路就是:
- 把列表分為兩個部分,一部分是已經排好序,一部分待排序。(這一點和選擇排序類似)
- 初始將第一個元素作為有序子列為,然後每次迭代從有序序列中移除;然後將它插入到有序序列中的相應位置。
- 重複以上步驟,直到到最後一個元素,則表示陣列有序。
圖示
可以通過動畫演示理解, 以下網上找的兩個動畫。如果你想操作不同的引數來演示,可以上這個網站visualgo.net動手試試。


程式碼實現
關於程式碼,README中程式碼只有實現演算法的函式,具體執行的程式碼,請檢視該目錄下的檔案。
程式碼如下:
const insertSort = (array) => { // 不修改原陣列 const originValues = array.slice(); // 初始將第一個元素指定為有序子列,從第2個元素開始插入,直到n-1元素 for (let i = 1; i < originValues.length; i++) { const currentValue = originValues[i]; // 標記插入有序子列的位置 let insertIndex = i; // 將當前元素從右到左與有序子列元素比較 // 起始位置為當前元素前一個元素,即i-1,終止位置為0 // 如果當前元素比該有序子列元素小,則該元素後移一位,並修改插入位置的遊標 for (let j = i-1; j > -1 && currentValue < originValues[j]; j--) { originValues[j+1] = originValues[j]; insertIndex = j; } // 插入指定位置 originValues[insertIndex] = currentValue; } return originValues; }; 複製程式碼
以上就是直接插入排序的程式碼實現。總體來說還是比較簡單易懂,其實就類似於打撲克,不斷將撲克牌按順序插入指定位置。唯一可能有一點容易想不清楚的,就是有序子列的右移部分。想清楚一點,只要有序子列的該元素大於要插入的元素,該元素就要後移一位。
演算法分析
1. 時間複雜度
排序演算法中,兩個元素的比較次數是影響執行時間的首要因素。所以我們可以通過這個層面來評估。
最優複雜度
當陣列有序時,每一次迭代只有一次比較,所以總共有n-1次比較,複雜度為O(n)。
最差複雜度
當陣列逆序時,每一次都要比較整個有序子列,比較次數為:
T(n) = 1 + 2 + ... + n-1 = n*n/2 複製程式碼
所以,最差複雜度是O(n 2 )。
2. 穩定性
因為比較元素是,相同值不會交換,所以插入演算法是穩定的。