前言
高手選擇排序的方式是根據(jù)具體的數(shù)據(jù)而選擇不同的排序,我們這些小菜鳥該怎么辦?當(dāng)然是快速排序一把梭(程序員不要提冒泡了),快排基本上能滿足你遇到的90%的排序需求,對于我們前端而言可能是99%。
算法原理
快速排序的基本思想是“分治”,“分治”的基本思想是把一個規(guī)模為N的問題分解成K個規(guī)模較小的子問題,這些子問題的相互獨立并且與原問題性質(zhì)相同,所以可以不斷的遞歸求解。
快速排序的方法如下:
- 在給出的一組數(shù)據(jù)中選出一個基準(zhǔn)值。
- 將這組數(shù)據(jù)中所有比基準(zhǔn)值大的數(shù)放在右邊,所有比基準(zhǔn)值小的數(shù)放在左邊,分界線就是該基準(zhǔn)值。
- 對基準(zhǔn)值左右兩邊的兩組數(shù)使用同樣的方式排序,不斷遞歸,直到所有數(shù)據(jù)排序完成。
具體實現(xiàn)
舉例:
[5, 2, 6, 9, 7, 3, 12]
- 選出基準(zhǔn)數(shù),基準(zhǔn)數(shù)的選擇一般常用的有兩種方式。第一種是選擇該組數(shù)據(jù)的第一個數(shù),第二種是生成一個數(shù)據(jù)總數(shù)量以內(nèi)的隨機(jī)數(shù),作為基準(zhǔn)數(shù)的數(shù)組索引,以此來選出基準(zhǔn)數(shù)。因為從理論上我們不知道要排序的具體數(shù)據(jù),因此使用第一種方式選擇的基準(zhǔn)數(shù)本身就是隨機(jī)的,一般情況下我們使用第一種方式選出基準(zhǔn)數(shù),比如此例中我們選擇5來作為基準(zhǔn)數(shù)。
- 要實現(xiàn)基準(zhǔn)數(shù)左邊數(shù)據(jù)都比其小,右邊數(shù)據(jù)都比起大,這一步依然有兩種方式。第一種是從數(shù)組左右兩邊分別開始搜索,從右邊開始向左查找,找到第一個比基準(zhǔn)數(shù)小的數(shù)3,然后再從左向右開始查找,找到第一個比基準(zhǔn)數(shù)大的數(shù)6,然后交換它們的位置,最后的數(shù)據(jù)為
[5, 2, 3, 9, 7, 6, 12]
依次執(zhí)行上面的步驟,設(shè)從左邊查找的索引為left,從右邊查找的索引為right,當(dāng)最后left = right時,將給位置的數(shù)和基準(zhǔn)數(shù)交換位置,最后結(jié)果為
[3, 2, 5, 9, 7, 6, 12]
第二種方法也被稱做“填坑”法,從有向做開始查找第一個小于基準(zhǔn)數(shù)的數(shù)3,然后將其填到left指向的位置[3, 2, 6, 9, 7, 3, 12],然后開始從左向右查找第一個大于基準(zhǔn)數(shù)的數(shù)6,將其填到right指向的位置[3, 2, 6, 9, 7, 6, 12],然后重復(fù)以上過程,最后將left = right時指向的位置填入基準(zhǔn)數(shù)5 ->[3, 2, 5, 9, 7, 6, 12] - 然后對基準(zhǔn)數(shù)左右部分的兩個數(shù)組[3, 2]和[9, 7, 6, 12]依次采用這種方法遞歸排序,最終得到排序完成的數(shù)組[2, 3, 5, 6, 7, 9, 12]
JavaScript代碼實現(xiàn):
/*第二步使用的是填坑法*/
/*
* data - 排序數(shù)組
* low - 數(shù)組最左端索引
* height - 數(shù)組最右端索引
*/
function quickSort(data, low, height) {
let sortData = data
let isLeft = true
let left = low,
right = height,
temp = sortData[left]
if (low >= height) {
return sortData
}
while (left !== right) {
if (isLeft) {
if (sortData[right] < temp) {
sortData[left] = sortData[right]
isLeft = !isLeft
} else {
right--
}
} else {
if (sortData[left] > temp) {
sortData[right] = sortData[left]
isLeft = !isLeft
} else {
left++
}
}
}
sortData[left] = temp
quickSort(sortData, low, left - 1)
quickSort(sortData, left + 1, height)
return sortData
}