feat: 添加基数排序

This commit is contained in:
= 2024-05-02 00:24:25 +08:00
parent 5c16f3f3a1
commit be99d65f05

81
sort/radix-sort.mjs Normal file
View File

@ -0,0 +1,81 @@
import insertionSort from './insertion-sort.mjs';
/**
* 使用lsd基数排序
* @param {number[]} arr - 要基数排序的数组
*/
export function radixSortByLsd(arr) {
let max = Math.abs(Math.max(...arr)); // 拿取数组中最大的数,用于计算长度
let buckets = Array.from({ length: 10 }, () => []);
let curDit = 1; // 当前比较的是哪个数位 1表示个位
/* 使
倒序添加到原数组的前面
*/
let negativeArr = [];
const tempArr = [];
for (let i = 0; i < arr.length; i++) {
const temp = arr[i];
if (temp < 0) {
negativeArr.push(temp);
} else {
tempArr.push(temp);
}
}
arr = tempArr;
if (negativeArr.length) {
negativeArr = radixSortByLsd(negativeArr.map((_) => -_)).map((_) => -_);
}
while (Math.floor(max)) {
for (let i = 0; i < arr.length; i++) {
buckets[getNumByGidit(arr[i], curDit)].push(arr[i]); // 根据数位的大小放入对应的数位桶中
}
// 对buckets中的每个桶的元素做好排序这里我们调用之前的插入排序
for (let i = 0; i < buckets.length; i++) {
insertionSort(buckets[i]);
}
// 个位比较完成之后比较十位,在此之前要把个位有序的数组给原数组,并且把桶子清空
arr = buckets.flat();
buckets = Array.from({ length: 10 }, () => []);
max /= 10; // 处理下一数位
curDit++;
}
return negativeArr.length ? negativeArr.reverse().concat(arr) : arr;
}
/**
* @description 获取某位的数字,从1开始1代表是个位比如1003返回的是13代表千位
* @param {number} num - 传入的数值
* @param {number} dit - 要获取的位数
*/
function getNumByGidit(num, dit) {
if (!num) return 0;
let res = 0;
while (dit--) {
res = num % 10;
num = (num - res) / 10;
}
return res;
}
/**
* @description 使用msd的基数排序
* @param {number[]} arr - 需要排序的数组
*/
export function radixSortByMsd(arr) {
// 获取最大值,并通过最大值对小的数补零
const maxVal = Math.max(...arr);
const n = arr.length; // 数组的个数
const radix = Math.floor(Math.log10(maxVal)); // 对应的位数比如100就是2代表百分位
// 从高位到地位开始比较,分别放入对应的桶中,再便利,使之相对有序
const buckets = Array.from({ length: 10 }, () => []);
for (let i = 0; i < n; i++) {
buckets[getNumByGidit(arr[i], radix + 1)].push(arr[i]);
}
// 对每一个桶中的内容进行msd基数排序如果零号桶还有的话
if (buckets[0].length) {
for (let i = 0; i < buckets.length; i++) {
buckets[i] = radixSortByMsd(buckets[i]);
}
}
return buckets.flat();
}