如何给广东省人口按照年龄来排序?
据统计,广东省人口已经突破一亿人,是中国人口最多的省份,那么我们如何快速给广东省人口按照年龄来排序呢?大家都知道快速排序的时间复杂度是O(nlogn),那还有比快速排序更快的算法吗?那就跟我来一探究竟。
计数排序
计数排序的思想很简单:当要排序 n 个数据,并且n的取值范围并不大的时候,比如最大值是k,我们就可以把数据划分成k个桶,每个桶内的数据值都是相同的。我们来观察一下年龄这个数据的特征是啥?我们假设最大的年龄是120岁,最小的年龄是0岁,那么年龄的数据范围是0-120岁,这就说明年龄的取值范围不大,正好符合计数排序的数据要求。所以我们可以分成121个桶,对应年龄0~120。我们根据人的年龄,将所有广东省的人口划入
这个121个桶里。桶内的数据都是年龄相同的人,所以不需要再排序。我们只需要依次扫描每个桶,将桶内的数据输出,就实现了广东省人口按年龄来排序,因为只是涉及到了遍历操作,所以时间复杂度是O(n)。
我们接下来来看一下计数排序的具体实现。我们还拿年龄的例子来看,为了方便说明,我们将数据规模进行了简化处理,假设只有7个人,年龄的范围是0~5。这7个人的年龄放在一个数组A中。他们分别是5,4,3,3,2,4,0。
年龄的范围是0~5,我们使用大小为6的数组C表示桶,其中数组的下标对应的是年龄,C数组存储的是对应年龄的人数。我们遍历一遍人口年龄数据,就可以给数组C初始化完成。
从图中可以看出,年龄为3的人数是2,小于3的人数有2个,所以,年龄为3的人在排序之后的有序数组中,会保存下标2,3的位置。
那我们如何快速计算出,每个年龄的人在有序数组中对应的存储位置呢?这个处理方法非常巧妙,很不容易想到。思路是这样的:我们对数组C顺序求和,数组C存储的数据就变成了下面这样子。C[k]里存储小于等于年龄k的人的个数。
接下来是最核心的部分了。我们从后到前依次遍历数组A。比如,当扫描到0时,我们从数组C中取出下标为0的值1,也就是说,到目前为止,包括自己在内,年龄小于等于 0 的人数有 1 个,也就是说 0 是数组 R 中的第 1 个元素(也就是数组 R 中下标为 0 的位置)。当0放入到数组 R 中后,小于等于 0 的元素就只剩下了 1 个了,所以相应的 C[0]要减 1,变成 0。当我们扫描完整个数组 A 后,数组 R 内的数据就是按照分数从小到大有序排列的了。
接下来,我们来看一下代码是如何实现的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | def countingSort(a,n): if n< = 1 : return #求出最大值 max_data = max (a) c = [ 0 for i in range (max_data + 1 )] #初始化C for j in a: c[j] + = 1 ##依次累加 for i in range ( 1 ,max_data + 1 ) : c[i] = c[i - 1 ] + c[i] r = [ 0 for i in range (n)] for i in range (n - 1 , - 1 , - 1 ): index = c[a[i]] - 1 r[index] = a[i] c[a[i]] - = 1 return r a = [ 5 , 4 , 3 , 3 , 2 , 4 , 0 ] r = countingSort(a, len (a)) print (r) |
总结一下,计数排序只能用在数据范围不大的场景中,如果数据范围 k 比要排序的数据 n 大很多,就不适合用计数排序了。而且,计数排序只能给非负整数排序,如果要排序的数据是其他类型的,要将其在不改变相对大小的情况下,转化为非负整数。
计数排序你学会了吗?欢迎留言和我一起讨论,更多有趣内容,请关注公众号。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现