手寫算法並記住它:插入排序

對於經典算法,你是否也遇到這樣的情形:學時以爲很清楚,可過陣子就忘了?javascript

本系列文章就嘗試解決這個問題。java

研讀那些排序算法,細品它們的名字,其實都很貼切。算法

好比插入排序,所謂「插入」,實指把待排序元素插入到已排好的序列裏。緩存

上圖演示了第4次遍歷,此時元素一、三、5已是有序序列,待排的元素是2,要把它插入到1和3之間。此時3和5都日後移動了一位。markdown

能夠看出該算法的核心是:如何在有序序列裏找到正確的插入位置?oop

思路是從有序序列的尾部開始,逐個與目標元素比較,若是大於目標元素,該元素須要後移。post

能夠看出之因此先要緩存一下目標,是爲了要把它的位置先空下來,方便其餘元素移入。 另外,當元素不大於目標時,此時說明要插入目標的位置已經找到了。spa

翻譯成代碼:翻譯

let array = [1, 3, 5, 2, 4]
let i = 3
let target = array[3]
while(i > 0 && array[i-1] > target) {
  array[i] = array[i-1]
  i--
}
array[i] = target
console.log(array) // [ 1, 2, 3, 5, 4 ]
複製代碼

能插入成功一個,遍歷n-1次(第一個元素自己就是有序序列了),就能夠所有插入,代碼很容易寫出來:code

for (let j = 1; j < array.length; j++) {
  let i = j
  let target = array[i]
  while(i > 0 && array[i-1] > target) {
    array[i] = array[i-1]
    i--
  }
  array[i] = target
}
複製代碼

查看完整代碼:codepen

至此,插入排序原理和實現已經說完了。

這裏總結一下,插入排序不須要額外空間,是本地排序,相等元素是不會交換先後順序,於是也是穩定排序,時間複雜度爲O(n^2),適用於少許數據排序。相比冒泡排序和選擇排序,插入排序的使用相對多一些。由於前二者是交換排序,本質上須要3次原子操做的。

插入排序,要作到能分分鐘手寫出來,是須要掌握其排序原理的。每次遍歷核心是找到正確的插入位置,一旦內層遍歷能寫出來,那麼總體就很容易寫出來,不須要死記硬背的。

但願有所幫助,本文完。



本系列已經發表文章:

相關文章
相關標籤/搜索