基数排序原理
假设现有一组待排序的数据
[13, 21, 11, 32, 31, 22, 21]
首先对这组数据的个位数进行计数
1 | 2 | 3 |
---|---|---|
4个 | 2个 | 1个 |
接着对原数组进行倒叙扫描,
首先是21, 21的个位数是1,因此21放在第4个“1”上;其次是22, 22的个位数是2,因此22放在第二个“2”上,后面的以此类推,最终结果如图所示:
接下来,以个位数的排序结果为基础,重复上述步骤。
首先统计十位数的计数
1 | 2 | 3 |
---|---|---|
2个 | 3个 | 2个 |
然后对该结果进行前缀和的求和,得到的结果是 [0, 2, 5, 7]
。这里的数字表示不同十位数计数的最后一个坐标加1,比如说按顺序排好的数组,十位数为1的数字排在前两个
接下来是对个位排序数组进行倒序扫描并插入到对应位置,得到的结果如下:
至此,该数据已经排序完毕
具体实现如下
function radixSort(data: number[], n: number) {
const counter = (new Array(65536) as any).fill(0),
temp = (new Array(n) as any).fill(0)
//* 低16位处理
data.forEach(num => counter[num & 0xffff]++)
for (let i = 1; i < 65536; i++) counter[i] += counter[i - 1]
for (let i = n - 1; i >= 0; i--) temp[--counter[data[i] & 0xffff]] = data[i]
//* 重置
counter.fill(0)
//* 高16位处理
data.forEach(num => counter[(num & 0xffff0000) >> 16]++)
for (let i = 1; i < 65536; i++) counter[i] += counter[i - 1]
for (let i = n - 1; i >= 0; i--) data[--counter[(data[i] & 0xffff0000) >> 16]] = temp[i]
}
在这里的实现中,低16位可以当作示例中的个位数,高16位可以当作示例中的十位数。
基数排序习题
leetCode 164 最大间距
这道题要想在线性时间复杂度和空间复杂度的条件下解决此问题,用基数排序是最合适的
我们只要先排序然后遍历数组得到最大差值就行了
function radixSort(nums: number[]) {
const counter = new