「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」。
概念及相关介绍
计数排序是一种牺牲空间来换取低时间复杂度的算法,同时它也是一种非比较型排序。(即计数排序会占用我们比较大的内存空间,因此仅仅适用于数据比较集中的情况,比如学生年龄的数量分布等)
核心在于将输入的数值转化为键存储在额外开辟的数组空间中。要求输入数据必须为确定范围的整数。
非比较型排序——不需要比较的排序方法(不基于元素比较),利用数组下标来确定元素的正确位置。
计数排序和桶排序、基数排序一同归并于非比较型排序,算法复杂度O(n),只要符合要求的数据,均可以遍历一遍即得到对应结果,因此在对应的业务场景下,性能还是非常的优越的。
算法概述
一、创建一个maxLength大小的数组
二、创建一个新数组bucketList,长度为maxLength + 1
三、遍历数组中的 元素,原数组中的元素作为bucketList数组的索引,原数组中的元素出现次数作为bucketList数组的值
四、遍历新数组,找出其中value大于0的值并且依次将对应索引作为元素填充到原数组中,每处理一次,对应新数组索引的value - 1,直到该元素为0,依次对此数据进行处理。
五、返回原数组
代码实现
function countSort(arr: number[]) {
const maxVal = Math.max(...arr);
const bucketList = new Array(maxVal + 1);
for (let i = 0; i < arr.length; i++) {
const key = arr[i];
const num = bucketList[key];
if (num) {
bucketList[key] = num + 1;
} else {
bucketList[key] = 1;
}
}
let currentIndex = 0;
for (let j = 0; j < maxVal + 1; j++) {
while (bucketList[j]) {
arr[currentIndex] = j;
bucketList[j] = bucketList[j] - 1;
currentIndex += 1;
}
}
return arr;
}
console.log(countSort([2, 3, 4, 2, 5, 1, 6, 4, 7]));