📜  DAA-基数排序(1)

📅  最后修改于: 2023-12-03 15:14:35.518000             🧑  作者: Mango

DAA-基数排序

基数排序是一种非比较排序算法,它将整数按位数切割成不同的数字,然后按每个位数分别比较。基数排序不仅可以用于整数排序,还可以用于字符串排序。

DAA即Divide and conquer based on digit operations,基于数字操作的分治算法。它通过计算每个数字出现的频率来排序。从个位数开始,依次按照数字出现频率排序,再依次进行十位数,百位数的排序,直到所有的数字被完全排序。

步骤
  1. 获取待排序数组的最大值,确定需要排序几次。

  2. 创建10个桶用于存储数字,分别代表0-9。

  3. 从低位到高位,对每个数字进行分桶。

  4. 将桶中的数字按顺序依次取出放回数组中,此时数组已经按当前位数排好序。

  5. 重复步骤3和4,直到数组完全排好序。

代码实现
/**
 * 基数排序 - DAA方法
 * @param {array} arr 带排序数组
 * @returns {array} 排序后的数组
 */
function radixSort(arr) {
  // 计算最大值,确定基数
  const maxNum = Math.max(...arr);
  const maxDigit = String(maxNum).length;

  // 分别按个位、十位、百位进行排序
  for (let digit = 1; digit <= maxDigit; digit++) {
    // 初始化桶
    let buckets = Array.from({ length: 10 }, () => []);

    // 将数字放入对应的桶中
    arr.forEach(num => {
      const digitNum = Math.floor((num / Math.pow(10, digit - 1)) % 10);
      buckets[digitNum].push(num);
    });

    // 将桶中的数字依次放回数组中
    arr = buckets.flat();
  }

  return arr;
}
时间复杂度

基数排序的平均时间复杂度为O(d(n+k)),其中d为数字位数,n为数组长度,k为每个数字位的取值范围。当d较小时,时间复杂度可以近似为O(n)。

空间复杂度

基数排序的空间复杂度为O(n+k),其中n为数组长度,k为每个数字位的取值范围。当k较小时,空间复杂度可以近似为O(n)。

参考资料