算法解析:felipernb/algorithms.js 中的计数排序实现
2025-07-09 04:54:08作者:胡唯隽
计数排序(Counting Sort)是一种非比较型的整数排序算法,这篇文章将详细解析felipernb/algorithms.js项目中实现的计数排序算法,帮助读者理解其工作原理和实现细节。
计数排序概述
计数排序是一种线性时间复杂度的排序算法,特别适用于整数排序。它的核心思想是通过统计每个元素出现的次数,然后根据统计结果将元素放回正确的位置。
算法特点
- 时间复杂度:O(n + k),其中n是元素数量,k是最大键值
- 空间复杂度:O(n + k)
- 稳定性:稳定的排序算法
- 适用场景:适合键值范围不大的整数排序
实现解析
辅助函数:maximumKey
const maximumKey = array => {
let max = array[0].key;
const length = array.length;
for (let i = 1; i < length; i++) {
if (array[i].key > max) {
max = array[i].key;
}
}
return max;
};
这个辅助函数用于找出数组中所有对象键值的最大值。它通过遍历数组,比较每个元素的key属性值,最终返回最大的key值。
主函数:countingSort
const countingSort = array => {
// 1. 找出最大键值
const max = maximumKey(array);
const auxiliaryArray = [];
const length = array.length;
let i;
// 2. 统计每个键值出现的次数
for (i = 0; i < length; i++) {
const position = array[i].key;
if (auxiliaryArray[position] === undefined) {
auxiliaryArray[position] = [];
}
auxiliaryArray[position].push(array[i]);
}
// 3. 重建排序后的数组
array = [];
let pointer = 0;
for (i = 0; i <= max; i++) {
if (auxiliaryArray[i] !== undefined) {
const localLength = auxiliaryArray[i].length;
for (let j = 0; j < localLength; j++) {
array[pointer++] = auxiliaryArray[i][j];
}
}
}
return array;
};
主函数分为三个主要步骤:
- 找出最大键值:使用maximumKey函数确定键值范围
- 统计键值出现次数:创建一个辅助数组,将相同键值的对象收集到一起
- 重建排序数组:按顺序遍历辅助数组,将元素放回原数组
算法优势
- 线性时间复杂度:当键值范围k不大时,性能优于比较型排序算法
- 稳定性:相同键值的元素保持原有相对顺序
- 简单直观:算法逻辑清晰,易于理解和实现
使用注意事项
- 输入数组中的每个对象必须包含key属性
- key属性的值必须是整数
- 当键值范围非常大时,空间效率会降低
性能分析
该实现的时间复杂度为O(n + k),其中n是元素数量,k是最大键值。空间复杂度也是O(n + k),因为需要额外的辅助数组来存储中间结果。
总结
felipernb/algorithms.js中的计数排序实现遵循了经典算法设计,代码简洁高效。理解这个实现有助于掌握计数排序的核心思想,并能在适当的场景下应用这种高效的排序算法。