直接插入排序的時間複雜度爲 O(n^2) ,相較於複雜度爲 O(nlogn) 的快速排序、歸併排序、堆排序、希爾排序,插入排序可謂相形見絀。可是,插入排序真的一無可取嗎? 答案是否認的,插入排序在實踐中的使用頻率是很高的,在一些場景下,甚至展示出完勝高級排序的效率。下面咱們一塊兒來看看。數組
因爲插入排序的實現很簡單,首先直接放出代碼:spa
function insertSort(arr) { let length = arr.length; for(let i = 1; i < length; i++) { let temp = arr[i]; let j = i; for(; j > 0; j--) { if(temp >= arr[j-1]) { break; // 當前考察的數大於前一個數,證實有序,退出循環 } arr[j] = arr[j-1]; // 將前一個數複製到後一個數上 } arr[j] = temp; // 找到考察的數應處於的位置 } return arr; } // example let arr = [2,5,10,7,10,32,90,9,11,1,0,10] console.log(insertSort(arr));
插入排序的思路跟整理撲克牌是同樣的,即每次拿到一張牌,按大小順序將其插入到合適的位置。那麼插入排序實際上就是:每次將一個數插入到有序的數組中去(初始一個數字天然有序)。3d
下面以實例結合代碼來分析一個插入排序的過程:code
因爲第一個數 6 是天然有序的,因此咱們從第二個數 5 開始考察, 將 5 取出與它的前一個數 6 比較,5 < 6, 將 6 複製到 5 的位置,5 向前移動繼續比較,此時 5 已經處於數組第一位,第一次排序結束,將 5 放入當前位置;對象
此時 [5, 6] 已經構成有序數組,考察 4,將 4 取出與它的前一個數 6 比較,4 < 6,將 6 複製到 4 的位置;4 向前移與 5 比較,4 < 5,將 5 複製到前一個 6 的位置,此時 4 處於數組第一位,第二趟排序結束。blog
後面的排序過程與前面分析的過程一致,總結一下就是:不斷將大於當前考察對象的數後移一位,直到找到考察對象應該處於的位置。有一個須要注意的點是,考察對象不必定是要一直向前移動到數組第一個位置才結束一趟排序,若是中間找到了合適的位置,這趟排序是能夠提早終止的。
舉例:排序
這一點正是插入排序的精髓所在!若是對一個已經有序的數組使用插入排序,插入排序只會遍歷數組一遍,時間複雜度退化爲 O(n);能夠想象,若是對一個接近有序的數組使用插入排序,其效率是很是可觀的,而不少時候咱們處理的數據是接近有序的,只需調整一些無序項,因此插入排序是頗有用的。ip