计数排序:用统计与定位快速排序

我用一个生动形象的比喻来帮你理解**计数排序(Counting Sort)**的原理。


计数排序的生动形象解释

想象你是一个老师,要给一群学生按考试成绩从低到高排队。成绩都是整数,范围是0到100分。

传统排序的难点

如果你让学生们两两比较成绩,排队可能很慢,尤其学生很多时。

计数排序的妙招

你决定先准备一个“成绩统计表”,表里有101个格子(0分到100分),每个格子用来记录有多少学生得了这个分数。


具体步骤

  1. 统计成绩
    你让每个学生告诉你自己的成绩,然后你在对应分数的格子里加1。
    比如有3个学生得了85分,85分格子里的数字就是3。

  2. 计算累计人数
    你从0分开始,依次把每个分数格子的数量加起来,得到“累计人数”。
    这样你就知道,所有成绩小于等于某分数的学生一共有多少。

  3. 确定每个学生的位置
    你再从后往前看每个学生的成绩,利用累计人数表,确定这个学生在排队中的准确位置。
    比如累计人数告诉你,85分的学生排在第50到第52位。

  4. 排好队
    按照计算的位置,把学生排好队,成绩从低到高。


为什么这样能排序?

  • 你不需要比较学生之间的成绩,只用统计每个成绩出现的次数。
  • 利用累计人数,直接算出每个成绩的学生应该排在哪个位置。
  • 这样就能快速把学生排成有序队伍。

总结

  • 计数排序就是“统计-累计-定位-排序”的过程。
  • 它利用成绩的范围有限,快速统计出现次数。
  • 适合整数且范围不大的数据。

小结表格

步骤操作描述作用
统计统计每个成绩出现的次数了解数据分布
累计计算累计人数确定每个成绩的排队区间
定位根据累计人数确定每个元素位置直接定位元素排序位置
排序按位置把元素放入结果数组得到有序序列

我们继续深入讲解计数排序的细节,包括它的实现步骤、适用场景、时间复杂度分析,以及一个简单的代码示例,帮助你更全面地理解计数排序。


计数排序的详细步骤

  1. 确定数据范围
    找出待排序数组中的最大值和最小值,确定计数数组的大小。

  2. 统计元素出现次数
    创建一个计数数组,长度为最大值减最小值加1,遍历原数组,统计每个元素出现的次数,存入计数数组对应位置。

  3. 计算累计计数
    对计数数组进行累加,得到每个元素在排序后数组中的结束位置。

  4. 构建排序结果
    从原数组末尾开始遍历,根据计数数组确定每个元素在结果数组中的位置,放入结果数组,并将计数减1。


计数排序的适用场景

  • 整数排序
    计数排序适合整数排序,尤其是数据范围不大的情况。

  • 数据范围有限
    当数据范围(最大值-最小值)不是特别大时,计数排序效率高。

  • 稳定排序需求
    计数排序是稳定排序,适合需要保持相同元素相对顺序的场景。


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

  • 时间复杂度:O(n + k),其中n是元素数量,k是数据范围大小。

    • 统计次数:O(n)
    • 计算累计:O(k)
    • 构建结果:O(n)
  • 空间复杂度:O(n + k),需要额外空间存储计数数组和结果数组。


计数排序的Python代码示例

def counting_sort(arr):
    if not arr:
        return arr

    min_val = min(arr)
    max_val = max(arr)
    range_val = max_val - min_val + 1

    # 1. 统计元素出现次数
    count = [0] * range_val
    for num in arr:
        count[num - min_val] += 1

    # 2. 计算累计计数
    for i in range(1, range_val):
        count[i] += count[i - 1]

    # 3. 构建排序结果
    output = [0] * len(arr)
    for num in reversed(arr):
        count[num - min_val] -= 1
        output[count[num - min_val]] = num

    return output

# 测试
arr = [4, 2, 2, 8, 3, 3, 1]
sorted_arr = counting_sort(arr)
print(sorted_arr)
# 输出: [1, 2, 2, 3, 3, 4, 8]

代码解析

  • 先确定数据范围,创建计数数组。
  • 统计每个元素出现次数。
  • 计算累计计数,确定元素排序位置。
  • 从后往前遍历原数组,保证排序稳定性。
  • 返回排序后的数组。

总结

  • 计数排序通过统计元素出现次数,利用累计计数直接定位元素位置。
  • 适合整数且范围不大的数据,时间复杂度接近线性。
  • 是稳定排序,空间开销较大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你一身傲骨怎能输

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值