手寫算法並記住它:選擇排序

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

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

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

好比選擇排序,所謂「選擇」,就是每次遍歷時,選擇一個最小的交換到已排好序列的後面。函數

上圖演示了第三次遍歷,此時元素1和2已經排好序,再在剩下的元素中找到最小的元素3,而後與目標位置交換。post

能夠看出該算法的核心是:如何在未排好序的元素中找到最小的元素?優化

這一點難不倒咱們,熊瞎子劈苞米,搞個變量記錄最小下標。ui

let array = [1, 2, 4, 5, 3]
let minIndex = 2
for (let i = 2; i < array.length; i++) {
  if (array[minIndex] > array[i]) {
    minIndex = i
  }
}
console.log(minIndex) // 4
複製代碼

找到了最小元素,而後再與目標位置的數據進行交換便可(若是剛好正在目標位置就不用交換了):spa

if (minIndex !== 2) {
  swap(array, 2, minIndex)
}
console.log(array) // [1, 2, 3, 5, 4]
複製代碼

其中swap函數封裝了兩個元素如何交換:code

function swap(array, i, j) {
  [array[i], array[j]] = [array[j], array[i]]
}
複製代碼

每次遍歷都排好一個最小的,n次遍歷就能排好全部,能夠輕鬆寫出代碼:cdn

let array = [4, 5, 3, 2, 1]
for (let j = 0; j < array.length; j++) {
  let minIndex = j
  for (let i = j; i < array.length; i++) {
    if (array[minIndex] > array[i]) {
      minIndex = i
    }
  }
  if (minIndex !== j) {
    utils.swap(array, j, minIndex)
  }
}
複製代碼

完整流程示意以下:

上述代碼,還有優化的空間,好比只須要遍歷n-1次就好了,由於最後一次,必然剩下了一個元素,不須要再作處理。查看完整代碼:codepen

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

這裏總結一下,選擇排序不須要額外空間,是本地排序,相等元素是不會交換先後順序,於是也是穩定排序,時間複雜度爲O(n^2),適用於少許數據排序,但實際中用得很少。

選擇排序,要作到能分分鐘手寫出來,是須要掌握其排序原理的。每次遍歷核心是找到最小元素而後與目標位置交換便可,一旦內層遍歷能寫出來,那麼總體就很容易寫出來,不須要死記硬背的。

但願有所幫助,本文完。



本系列已經發表文章:

《手寫算法並記住它:冒泡排序》

相關文章
相關標籤/搜索