新年伊始,又到了金三銀四的時候了。面對前端愈來愈多的算法面試題,我簡單的整理了一下幾種比較常見的數組排序方式,分別介紹其基本原理和優劣勢。(ps:才疏學淺,但願你們能夠在issues下面指出問題)javascript
選擇排序從數組內遍歷出最大值,加入新數組,將最大值從原數組中刪除,重複上述操做,最後得出的新數組就是一個從大到小排序的數組了。前端
/** * params {number[]} list * return {number[]} */
function sort(list) {
list = [...list]; // 最好不要對元素組操做
const newList = []; // 建立待返回的空數組
while(list.length) { // 當 list.length === 0 時,表示處理完畢
let min = Infinity; // 設最小值無窮大 或者 等於 list 中的任意位置均可
let minIndex; // 記錄下最小值下標
list.forEach((el, index) => { // 對 list 循環,查找當前 list 最小值
if(el < min) {
min = el;
minIndex = index;
}
});
newList.push(list[minIndex]); // 將 最小值下標 對應的值 push 進數組
list.splice(minIndex, 1); // 從list內刪除這個值
}
return newList
}
複製代碼
優勢:java
缺點:面試
桶排序顧名思義,就是準備好一些「桶」,而後將待排序的數組值一個個放入對應的「桶內」,所有元素放入」桶「後,而後展開」桶「就獲得了排序完成的數組了。好比:當前須要排序的數組 [8, 3, 5, 9, 2, 3, 0, 8],咱們能夠準備一個長度爲10的數組,每一項的值爲0,咱們對須要排序的數組開始便利,當咱們遇到8時,咱們將newList[8]內的0,加1,改爲1;而後下一個3,咱們將newList[3]內的0,加1,改爲1...,處理完全部元素後,將newList便利輸出就獲得了排序好的數組了。固然了這裏只是簡單的對桶排序的介紹,真正的桶排序確定比這個複雜。算法
const list = [8, 3, 5, 9, 2, 3, 0, 8]; // 待排序數組
/** * params {number[]} list * return {number[]} */
function sort(list) {
const newList = Array.from({length: 10}).fill(0); // 建立 [0, 0, ..., 0] 的數組,長度爲10
list.forEach(el => newList[el] += 1); // 把數組元素記錄在 newList 上
return newList.reduce((pre, el, index) => { // 展開數組
for(let i = el; i; i--) {
pre.push(index)
}
return pre;
}, [])
}
複製代碼
優勢:數組
缺點:ui
空間消耗比較大spa
須要提早知道最大值,最小值code
冒泡排序我先介紹說它的原理,你就明白它爲何叫冒泡排序了。有一個待排序的數組 [8, 3, 5, 9, 2, 3, 0, 8] ,須要由小到大排序。咱們只須要把小的放在左邊,大的放右邊是否是就完成了排序呢?顯然是的。將第一個 8 與 第二位 3 比較,8 大於 3,因此咱們把8往右放,即將 8 與 3 更換位置,更換後的數組是 [3, 8, 5, 9, 2, 3, 0, 8] ,繼續比較改變後的數組第二位 8 與 第三位 5 比較,8 大於 5,更換後的數組是 [3, 5, 8, 9, 2, 3, 0, 8],重複這樣的操做,若是遇到相同或者當前數值小於後一位的則不須要改變,繼續比較下一位便可。因此看這 8 的移動軌跡,像不像是一個氣泡在往上冒,因此這個排序方法就叫冒泡排序。排序
/** * params {number[]} list * return {number[]} */
function sort(list) {
list = [...list];
let length = list.length;
while(length--) {
for(let i = 0; i < length; i++) {
const current = list[i];
const next = list[i + 1];
if(current > next) {
[list[i], list[i + 1]] = [next, current];
}
}
}
return list;
}
複製代碼
優勢:
缺點:
中心思想是用二分實現的快速排序,可以很快的完成排序任務,也是我比較推薦的一種排序方式。
快速排序的優勢就是速度快,爲何速度快呢?我先介紹一下快速排序的原理。選擇一個基準值,通常選擇數組的一個值,遍歷數組,大的放右邊,小的放左邊,同樣大的放中間(哈哈哈哈哈😀),利用遞歸重複對大的數組和小的數組進行拆分,最後得出排序後的數組。
function quickSort(arr) {
if(arr.length < 2) {
return arr;
} else {
const pivot = arr[0]; // 基準值
const pivotArr = []; // 同樣大的放中間
const lowArr= []; // 小的放左邊
const hightArr = []; // 大的放右邊
arr.forEach(current => {
if(current === pivot) pivotArr.push(current);
else if(current > pivot) hightArr.push(current);
else lowArr.push(current);
})
return quickSort(lowArr).concat(pivotArr).concat(quickSort(hightArr));
}
}
複製代碼
優勢:
缺點: