首页
/ 算法解析:felipernb/algorithms.js 中的计数排序实现

算法解析:felipernb/algorithms.js 中的计数排序实现

2025-07-09 04:54:08作者:胡唯隽

计数排序(Counting Sort)是一种非比较型的整数排序算法,这篇文章将详细解析felipernb/algorithms.js项目中实现的计数排序算法,帮助读者理解其工作原理和实现细节。

计数排序概述

计数排序是一种线性时间复杂度的排序算法,特别适用于整数排序。它的核心思想是通过统计每个元素出现的次数,然后根据统计结果将元素放回正确的位置。

算法特点

  1. 时间复杂度:O(n + k),其中n是元素数量,k是最大键值
  2. 空间复杂度:O(n + k)
  3. 稳定性:稳定的排序算法
  4. 适用场景:适合键值范围不大的整数排序

实现解析

辅助函数: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;
};

主函数分为三个主要步骤:

  1. 找出最大键值:使用maximumKey函数确定键值范围
  2. 统计键值出现次数:创建一个辅助数组,将相同键值的对象收集到一起
  3. 重建排序数组:按顺序遍历辅助数组,将元素放回原数组

算法优势

  1. 线性时间复杂度:当键值范围k不大时,性能优于比较型排序算法
  2. 稳定性:相同键值的元素保持原有相对顺序
  3. 简单直观:算法逻辑清晰,易于理解和实现

使用注意事项

  1. 输入数组中的每个对象必须包含key属性
  2. key属性的值必须是整数
  3. 当键值范围非常大时,空间效率会降低

性能分析

该实现的时间复杂度为O(n + k),其中n是元素数量,k是最大键值。空间复杂度也是O(n + k),因为需要额外的辅助数组来存储中间结果。

总结

felipernb/algorithms.js中的计数排序实现遵循了经典算法设计,代码简洁高效。理解这个实现有助于掌握计数排序的核心思想,并能在适当的场景下应用这种高效的排序算法。