algorighm/sort/count-sort.mjs

61 lines
1.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @description 计数排序, 只能对大于零的整数排序
* @param {number[]} arr - 需要排序的数组
*/
export function countSort(arr) {
const len = arr.length;
const counts = []; // 用于计数的数组
// 遍历整个数组
for (let i = 0; i < len; i++) {
const el = arr[i];
counts[el] = counts[el] ? counts[el] + 1 : 1;
}
let index = 0;
for (let i = 0; i < counts.length; i++) {
let time = counts[i];
while (time) {
// 当桶子不为空时遍历time次
arr[index++] = i;
time--;
}
}
return arr; // 返回与不反都可以,本身就是对原数组的操作
}
/**
* @description 修改后的计数排序,支持负数
* @param {number[]} arr - 要排序的整数数组
*/
export function countSort2(arr) {
// 先找出最大值和for
const n = arr.length;
let min = arr[0];
let max = arr[0];
for (let i = 0; i < n; i++) {
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
// 计算计数数组的大小
const size = max - min + 1;
const counts = new Array(size).fill(0);
// 遍历原数组把"值-min"作为计数数组的下标, 值-min能保证下标永 远不会小于零
for (let i = 0; i < n; i++) {
counts[arr[i] - min]++;
}
// 遍历counts数组 累计前面的下下标值
for (let i = 1; i < size; i++) {
counts[i] += counts[i - 1];
}
const ret = [];// 排序后的新数组
// 现在数组的下表就是值,值就是下标
for (let i = n - 1; i >= 0; i--) {
counts[arr[i] - min]--; // 假设我们有三个数放入counts中counts[0]=1,counts[1]=2,counts[2]=3,所以要先减1再做下标使用
ret[counts[arr[i] - min]] = arr[i];
}
return ret;
}