计数排序并不是传统意义的比较排序,即并非通过数字之间的相互比较来决定顺序。
思想:
遍历数组arr,将arr[i]所为索引,arr[i]出现的次数作为值存入新的数组中,通常称为桶,因为arr[i]就是新数组中的索引,这个数字越大,在桶中的位置越靠后,这个过程即是在排序。
例如:arr = [1,4,3,0,2,1];
在桶里的结果就是bucket = [1,2,1,1,1,0];
解释:桶数组里,索引为0,就是arr[3],出现了一次,所以bucket[0] = 1,
索引为1,就是arr[0],出现了一次,所以bucket[1] = 1,
......
索引为4, 就是arr[2],出现了一次,bucket[4] = 1,
索引为5,在arr中没有,即出现0次,所以bucket[5] = 0
动图演示如下:
注意,如果数值太大会导致桶的容量很大。
代码实现如下:
let numbers = [54, 68, 12, 34, 3, 2, 5, 61, 5, 4, 84, 94];
function getMax(arr) {
return Math.max(...arr);
}
function countingSort(arr, max) {
let bucket = new Array(max + 1);
let len = arr.length;
let bucketLen = max + 1;
for (let i = 0; i < len; i++) {
if (!bucket[arr[i]]) {
bucket[arr[i]] = 0;
}
bucket[arr[i]]++;
}
let output = [];
for (let j = 0; j < bucketLen; j++) {
while (bucket[j] > 0) {
output.push(j);
bucket[j]--;
}
}
return output;
}
console.log(countingSort(numbers, getMax(arr)));
这种排序算法速度会比较快,但是相应的会导致空间复杂度很高。