怎样在JavaScript中实现计数排序?

来源:IPIPP.com作者:头衔:全栈工程师
导读:本期聚焦于小伙伴创作的《怎样在JavaScript中实现计数排序?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《怎样在JavaScript中实现计数排序?》有用,将其分享出去将是对创作者最好的鼓励。

计数排序是一种线性时间复杂度的排序算法,不需要进行元素之间的比较,只适合处理一定范围内的整数排序场景,在JavaScript中实现计数排序逻辑清晰,实用性较强。

怎样在JavaScript中实现计数排序?

计数排序的核心原理

计数排序的核心思路是:先统计待排序数组中每个元素出现的次数,然后根据统计结果,将元素按顺序回填到原数组或者新数组中完成排序。它要求待排序的元素都是整数,并且元素的范围不能太大,否则会占用过多的额外空间。

计数排序是稳定排序,相同元素的相对顺序在排序后不会改变,这一点在对对象按照某个整数属性排序时非常有用。

JavaScript实现计数排序的步骤

实现计数排序主要分为以下几个步骤:

  • 遍历待排序数组,找到数组中的最大值和最小值,确定元素的范围
  • 创建一个计数数组,长度为最大值减去最小值加一,用来统计每个元素出现的次数
  • 再次遍历待排序数组,针对每个元素,将计数数组中对应位置的值加一
  • 对计数数组做前缀和处理,这样每个位置的值就表示该元素排序后应该放置的最后位置
  • 从后往前遍历待排序数组,根据计数数组的结果将元素放到结果数组的对应位置,同时更新计数数组的值,保证稳定性
  • 将结果数组拷贝回原数组,完成排序

完整JavaScript实现代码

下面是支持整数范围、保证稳定性的计数排序完整实现:

/**
 * JavaScript计数排序实现
 * @param {number[]} arr 待排序的整数数组
 * @returns {number[]} 排序后的数组
 */
function countingSort(arr) {
    if (arr.length <= 1) {
        return arr;
    }
    // 找到数组的最小值和最大值
    let min = arr[0];
    let max = arr[0];
    for (let i = 1; i < arr.length; i++) {
        if (arr[i] < min) {
            min = arr[i];
        }
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    // 创建计数数组,长度为max - min + 1
    const countLen = max - min + 1;
    const countArr = new Array(countLen).fill(0);
    // 统计每个元素出现的次数
    for (let i = 0; i < arr.length; i++) {
        const index = arr[i] - min;
        countArr[index]++;
    }
    // 计数数组做前缀和处理
    for (let i = 1; i < countLen; i++) {
        countArr[i] += countArr[i - 1];
    }
    // 创建结果数组,从后往前遍历保证稳定性
    const result = new Array(arr.length);
    for (let i = arr.length - 1; i >= 0; i--) {
        const index = arr[i] - min;
        const position = countArr[index] - 1;
        result[position] = arr[i];
        countArr[index]--;
    }
    // 将结果拷贝回原数组
    for (let i = 0; i < arr.length; i++) {
        arr[i] = result[i];
    }
    return arr;
}

// 测试示例
const testArr = [4, 2, 8, 2, 5, 1, 4, 6];
console.log("排序前:", testArr);
countingSort(testArr);
console.log("排序后:", testArr);

计数排序的复杂度与适用场景

计数排序的时间复杂度为O(n + k),其中n是待排序数组的长度,k是元素的范围大小;空间复杂度为O(k + n),需要额外的计数数组和结果数组。

它的适用场景非常明确:

  • 待排序元素都是整数
  • 元素的范围k不是特别大,否则会浪费大量空间
  • 需要稳定排序的场景,比如按照年龄排序用户对象时,相同年龄的用户保持原有顺序

如果待排序的元素是浮点数,或者元素范围非常大(比如从1到1000000只有10个元素),就不适合使用计数排序,此时可以选择快速排序、归并排序等其他算法。

常见问题说明

很多开发者会疑惑为什么要从后往前遍历原数组放元素,这是因为计数排序要保证稳定性,从后往前遍历可以让相同元素按照原来的相对顺序放入结果数组。如果不需要稳定性,也可以从前往后遍历,不过大多数场景下建议保留稳定性,适用范围更广。

另外如果待排序数组的元素都是正整数,也可以简化实现,不需要处理最小值,计数数组长度直接为最大值加一,不过支持最小值的实现能处理包含负整数的场景,通用性更强。

计数排序JavaScript排序算法稳定排序时间复杂度线性排序修改时间:2026-05-29 22:39:59

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。