本系列的文章列表和相關說明,請查看序言。具體列表以下:
【一塊兒學習排序算法】0 序言
【一塊兒學習排序算法】1 算法特性及大O記法
【一塊兒學習排序算法】2 冒泡排序javascript
也能夠直接到github上查看完整的文章和源碼!html
本篇爲此係列第三篇。java
先看看Wikipedia的定義:git
The Selection sort algorithm divides the input list into two parts: the sublist of items already sorted and the sublist of items remaining to be sorted that occupy the rest of the list. Initially, the sorted sublist is empty and the unsorted sublist is the entire input list. The algorithm proceeds by finding the smallest element in the unsorted sublist, exchanging it with the leftmost unsorted element, and moving the sublist boundaries one element to the right. .github
因此選擇排序的思路就是:算法
能夠經過動畫演示理解, 如下網上找的動畫。若是你想操做不一樣的參數來演示,能夠上這個網站visualgo.net動手試試。數組
關於代碼,README中代碼只有實現算法的函數,具體運行的代碼,請查看該目錄下的文件。bash
代碼以下:數據結構
const selectSort = (array) => {
// 不修改原數組
const originValues = array.slice();
const length = originValues.length;
// 迭代次數 數組長度-1, 由於前n個元素有序,則所有有序
for (let i = 0; i < length - 1; i++) {
// 把當前無序子列的第一個元素當作最小值
let minIndex = i;
// 找出最小值的索引
for (let j = i+1; j < length; j++) {
if (originValues[j] < originValues[minIndex]) {
minIndex = j;
}
}
// 若是最小值不爲當前值,交換
if (minIndex !== i) {
const tmp = originValues[i];
originValues[i] = originValues[minIndex];
originValues[minIndex] = tmp;
}
}
return originValues;
};
複製代碼
選擇排序仍是比較簡單的,基本知道原理,看了註釋就很明白了。有一點要說的是,就是在找最小值這個步驟。不少文章的實現,在發現當前值小於當前最小值時,就交換元素。這種交換仍是不必的,只要先記住最小值得下標minIndex
就能夠,最後一步來作交換。這樣就減小了不少沒必要要的交換要素,後來發現和wikipedia的實現如出一轍(第一次也是惟一一次,哈哈)。ide
時間複雜度
選擇排序,無論數組正序仍是逆序,都是同樣的操做。最優複雜度和最差複雜度都是O(n2)。
穩定性
由於可能存在和最小值元素交換是,把數值相同的元素順序調換,因此,選擇排序是不穩定的排序。
舉個例子吧:
[3] 5 2 (3) 1
複製代碼
因爲最小的元素1在最後一個,須要和[3]
元素交換,此時[3]
就到(3)
後面了。
有文章說選擇排序是穩定的,其實看具體的實現。在《算法》第四版217頁上做者已經說了,有不少辦法能夠將任意排序算法變成穩定的,可是,每每須要額外的時間或者空間。摘自知乎
本章節介紹了幾種選擇排序的實現。選擇排序應該是最簡單的排序了,不過效率也是很低,複雜度仍是O(n2)。
[1] 動畫演示
[2] tutorials point 教程
[3] 選擇排序究竟屬於穩定排序仍是不穩定排序?
[4] Sorting Algorithms
[5] 凱耐基梅隆大學數據結構與算法-排序算法
[6] CMU algorithm complexity