線性排序:Bucket sort,Counting sort,Radix sort
桶排序
- 數據能劃分為m個桶,桶之間有天然有序;
- 數據在各個桶之間分布均勻;
計數排序
數據范圍不大的非負整數排序
function countingSort(arr) {
let min = arr[0], max = arr[0];
arr.forEach((item) => {
min = min < item ? min : item;
max = max > item ? max : item;
});
let n = max - min + 1, countList = [];
for (let i = 0; i < n; i++) {
countList.push(0);
}
arr.forEach((item) => {
countList[item - min]++;
});
let result = [];
// 方法1: 累加,逆序求值
for (let i = 1; i < n; i++) {
countList[i] += countList[i-1];
}
for (let i = arr.length-1; i >= 0; i--) {
let val = arr[i];
let j = countList[val-min];
result[j-1] = val;
countList[val-min]--;
}
// 方法2: 遞減取值
// for (let i = 0; i < countList.length; i++) {
// while(countList[i] > 0) {
// result.push(i+min);
// countList[i]--;
// }
// }
return result;
}
基數排序
- 有獨立分割的位,高低位有遞進關系;
- 每位數據范圍不可太大,要可以用線性排序。
例:手機號碼,低位到高位每位穩定排序,k位整數=k次桶排序or計數排序
function radixSort(arr) {
let n = 0;
arr.forEach(item => {
let tmpLen = String(item).length;
n = tmpLen > n ? tmpLen : n;
});
let bucket = [], result = [], max = n;
while (n > 0) {
n--;
result = [];
bucket = [];
for (let i = 0; i <= 9; i++) {
bucket[i] = [];
}
arr.forEach(item => {
let val = String(item);
let prefix = max - val.length;
while(prefix > 0) {
val = "0" + val;
prefix--;
}
let key = val.charAt(n) || 0;
bucket[key].push(item);
});
for (let i = 0; i <= 9; i++) {
if (bucket[i].length > 0) {
result = result.concat(bucket[i]);
}
}
arr = result;
}
return result;
}