一种非比较排序,他是对一些关键字进行分类收集的一种排序方法,比如我们数字可以按照个位、十位、百位….
对于普通数字比较来说我们可以类比计数排序和桶排序
基数排序:根据键值的每位数字来分配桶
计数排序:每个桶只存单一键值
桶排序:每个桶存一定范围的值
算法思路:
1、确定序列的关键字并对其进行分类(个位、十位,百位…)
2、对于每一次分类的结果进行关键字排序,然后输出
举例子:
比如序列 [ 3, 4, 6, 2, 1, 6, 95, 2, 5, 7, 288, 45, 53, 334, 581 ]
第一步:对个位进行计数排序得到 [ 1, 581, 2, 2, 3, 53, 4, 334, 95, 5, 45, 6, 6, 7, 288]
第二步:对十位进行计数排序得到 [ 1, 2, 2, 3, 4, 5, 6, 6, 7, 334, 45, 53, 581, 288, 95]
第三部:对百位进行计数排序得到 [ 1, 2, 2, 3, 4, 5, 6, 6, 7, 45, 53, 95, 288, 334, 581]
完毕
代码
function RadixSort(nums){let digitNumber = 1 // 分类的数量for (let j = 0; j < nums.length; j++) { // 找到最大位digitNumber = Math.max(digitNumber, nums[j].toString().length) // 确定最大分类数量}let div = 1, mod = 10, count = new Array(20) // 数字每一位只有-9 - 9, 实际19个,为了方便记忆我们计为20个for (let i = 0; i < digitNumber; i++, div*=10, mod*=10) {for (let j = 0; j < nums.length; j++) {let buncket = parseInt(nums[j] % mod / div) // 对应个、百..位 位置上的桶编号buncket += 10 // 处理负数,把数字偏移右10位(实际只需要9位)count[buncket] = count[buncket] || []count[buncket].push(nums[j])}let pos = 0for (let j = 0; j < count.length; j++) {if(count[j]){while(count[j].length){ // 依次输出到原数组中nums[pos++] = count[j].shift()}}}}return nums}
时间复杂度O(k * n) k指代分类的总数,但是通常k是一个比较小的常数
空间复杂度(O(n + k))
稳定性而言,每次分类排序采用的稳定的计数排序,所以是稳定的
