TypeScript实现十大排序算法(八) - 计数排序

430 阅读4分钟

一. 计数排序的定义

计数排序是一种非比较型整数排序算法。它的核心思想是对于待排序的数组,统计每个数出现的次数,然后根据次数从前往后依次输出。

计数排序的时间复杂度为O(n),这使得它比其他排序算法快得多,特别是当待排序的数据量很大,但是其空间复杂度却较高。

优点:

  1. 时间复杂度低,只需要O(n)的时间复杂度。
  2. 易于实现。
  3. 对于数据范围很小的情况下,它可以达到稳定性。

缺点:

  1. 空间复杂度高,需要额外的存储空间。
  2. 仅适用于整数数据的排序。
  3. 不适用于浮点数和负数的排序。

二. 计数排序的流程

计数排序的流程分析:

  1. 首先确定数列的范围,并创建一个对应的桶列表,每个桶代表一个数列中的值;
  2. 然后遍历原数列,并统计每个数列中值出现的次数,并将次数加入对应的桶中;
  3. 接下来将桶列表转换为前缀和数组,即统计每个桶前面所有桶的数值总和;
  4. 最后遍历原数列,对于每个数,将它插入对应的桶中的对应位置,位置确定的方法是:将该数的数值减去数列的最小值,然后加一,再在前缀和数组中找到该数的前一个数的位置,这个位置即为该数的插入位置。

通过这样的步骤,我们就可以得到一个从小到大排序的数列。

三. 计数排序的图解

整体流程:

计数排序

四. 计数排序的代码

下面是TypeScript实现的计数排序代码,带有详细的注释:

function countingSort(array: number[]): number[] {
  const n = array.length;

  // 计算数列最大值和最小值
  let max = array[0];
  let min = array[0];
  for (let i = 1; i < n; i++) {
    if (array[i] > max) {
      max = array[i];
    }
    if (array[i] < min) {
      min = array[i];
    }
  }

  // 统计数列中每个值出现的次数
  const count = new Array(max - min + 1).fill(0);
  for (let i = 0; i < n; i++) {
    count[array[i] - min]++;
  }

  // 累加数组
  for (let i = 1; i < count.length; i++) {
    count[i] += count[i - 1];
  }

  // 从后向前遍历原始数组,按照统计数组中的位置放置元素
  const res = new Array(n);
  for (let i = n - 1; i >= 0; i--) {
    res[--count[array[i] - min]] = array[i];
  }

  return res;
}

在上面的代码中,我们首先定义了一个名为countingSort的函数

  • 该函数接受两个参数:待排序数组arr和数组中元素的最大值maxValue。

  • 接下来,我们创建了一个大小为maxValue + 1的数组count,该数组用于统计数字出现的次数。

  • 接着,我们使用for循环对数组arr中的每个元素进行处理,并统计每个数字出现的次数。

  • 最后,我们遍历数组count,并使用for循环把它的元素按照统计的次数逐个输出到结果数组中,最终得到有序数组。

五. 计数排序的时间复杂度

计数排序的时间复杂度分析如下:

  • 预处理:建立一个计数数组,把输入数组中每个数字出现的次数存入计数数组。

    • 时间复杂度:O(k),其中k是数字的取值范围。
  • 累加:遍历计数数组,把每个数字出现的次数加上它前面数字出现的次数。

    • 时间复杂度:O(k)
  • 输出:遍历输入数组,把每个数字存入输出数组对应的位置。

    • 时间复杂度:O(n),其中n是输入数组的长度。

因此,计数排序的总时间复杂度为:O(k + n)。

计数排序对于长度较短,数字取值范围较小的数组是非常高效的。

六. 计数排序的总结

计数排序是一种特殊的排序算法:

  • 其不同于其他算法的地方在于它不依赖于比较,而是通过计算每个元素的出现次数,来确定每个元素的排名。

计数排序的复杂度为 O(n+k),其中 k 是数组中出现的数的范围。

  • 因此,计数排序非常适合数据范围较小的数组,并且可以很快地对数组进行排序。
  • 但是,由于需要额外的存储空间来存储每个数的出现次数,因此不适合大数据量的数组。

总的来说,计数排序是一种非常有效的排序算法,在适当的情况下可以使用。

coderwhy公众号分享各种编程技术、生活、感悟,欢迎关注、交流、分享。