业界动态
计数排序:数不尽的奇妙与高效
2024-12-29 22:01

,各位编程界的探索者们,今天咱们来聊一个既简单又高效的排序算法——计数排序(Counting Sort!想象一下,如果算法世界也有人口普查,那计数排序绝对是个条理清晰、效率奇高的“统计员”。

  • 基本信息:计数排序是一种稳定的排序算法。计数排序使用一个额外的数组 ,其中第 个元素是待排序数组 中值等于i的元素的个数。然后根据数组 来将A中的元素排到正确的位置。它只能对整数进行排序。核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

  • 时间复杂度:在最佳和最坏情况下,计数排序都是,其中是待排序数组的长度,k是数组中元素的最大值。这简直就像是给数组做了个“全身扫描”,速度嗖嗖的。

  • 空间复杂度:计数排序的空间复杂度为,因为它需要一个大小为的辅助数组来存放每个元素的出现次数。这就好比给每个可能的数值都准备了一个“小盒子”,虽然有点占地方,但效率高啊

  • 稳定性算法:计数排序是稳定的,这意味着如果两个元素相等,它们在排序后的相对位置不会改变。就像是一群排队买票的人,即使身高相同,谁先来谁就在前面,公平公正。

现在,你是不是已经对计数排序产生了浓厚的兴趣?别急,咱们继续深入,看看它的原理是如何让人拍案叫绝的。


计数排序的原理其实超级直观,就像我们小时候玩的分类游戏一样。假设你有一堆颜色各异的积木,想要把它们按照颜色分类,最快的方法不就是每种颜色放一堆吗?计数排序也是这个思路,只不过它处理的是数字。

  1. 找出最大值:首先,遍历一遍待排序数组,找出数组中的最大值,这个最大值将决定辅助数组的大小。
  2. 初始化辅助数组:创建一个大小为最大值+1的辅助数组(为啥+1?因为数组索引从0开始嘛,并将所有元素初始化为0。这个辅助数组就像是一个“计数器”,记录每个数字出现的次数。
  3. 填充辅助数组:再次遍历待排序数组,每遇到一个数字,就在辅助数组对应索引的位置上加1。这样,辅助数组就记录下了每个数字的出现次数。
  4. 构建排序结果:最后,根据辅助数组的信息,依次将数字填入结果数组中。比如,如果辅助数组在索引2的位置上有3个,那就意味着数字2在结果数组中要连续出现3次。
  • 栗子1:数组[4, 2, 2, 8, 3, 3, 1]

    • 找出最大值:8
    • 初始化辅助数组:[0, 0, 0, 0, 0, 0, 0, 0, 0](因为最大值是8,所以数组长度为9
    • 填充辅助数组:[0, 1, 2, 2, 1, 0, 0, 0, 1](根据原数组更新
    • 构建排序结果:[1, 2, 2, 3, 3, 4, 8](按照辅助数组的信息
  • 栗子2:数组[5, 3, 8, 3, 1, 7, 9, 2, 5]

    • 找出最大值:9
    • 初始化辅助数组:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0](因为最大值是9,所以数组长度为10
    • 填充辅助数组:[1, 1, 1, 0, 2, 0, 1, 0, 1, 1](根据原数组更新
    • 构建排序结果:[1, 2, 3, 3, 5, 5, 7, 8, 9](按照辅助数组的信息

怎么样,是不是觉得计数排序既简单又巧妙?接下来,咱们来看看如何在不同的编程语言中实现它。


 
 
 
 
 
 
 

怎么样,是不是觉得每种语言的实现都各有千秋,但都同样简洁高效?接下来,咱们来点实战,看看在洛谷上如何用计数排序解决具体问题。


优化版计数排序
正常版本的计数排序当有几个相同元素时,会改变原来元素相对位置,是不稳定排序,因此需要优化。

3.1 优化的思路
主要是将排序数组sortArr里非零元素作为权值依次加入到后面元素里。具体示例如下所示

排序数组sortArr总共弄有334个元素
sortArr: 0 1 2 3 4 5 6 7 8 9 10 … 87 … 99 … 333
count: 2 2 2 0 0 1 1 0 1 0 1 0 1 0 1 0 1

变化后排序数组sortArr(Di == Di-1 + Di-2 : 后面的元素等于前面非零元素之和)

 

第333次变化后的排序数组sortArr的值即是输出有序数组的下标,索引即是缩放后的元素。代码实现如下

for (auto& it : sortArr) // 遍历排序数组,将前面非零元素依次累加到后面
{
if (it)
tmp += it; // 非零则累加
it = tmp; // 变化后元素
}
// 经过上面的变化,此时排序数组sortArr的元素即为初始数组元素排序后的位置
那么问题来了,该如何还原排序后元素呢

答案很简单,因为变化后排序数组sortArr的值是原始数组nums元素排序后索引下标,所以只需要依次遍历原始数组nums,然后找打对应下标,将该原始数组的元素依次取出排列到有序数组即可,代码实现如下

for (int i = nums.size(); i > 0; --i) // 逆序遍历原始数组,找到对应位置输出有序数组
{
int index = sortArr[nums[i - 1]] - 1; // 找到元素nums[i-1]排序后位置索引;sortArr[ nums[i-1] ]的值表示元素nums[i-1]在有序数组中排第几个位置
result[index] = nums[i - 1];
sortArr[nums[i - 1]]–; // 排序数组取出一个元素排列后,该元素的值需要减一,即如果下次还命中该相同元素,则往后一位排列
}
nums = result;
3.2 优化计数排序跟基本计数排序主要区别
3.2.1变化后的排序数组sortArr存储的元素值不同
基本计数排序的排序数组sortArr存储的是初始化数组nums每个元素个数,而优化后计数排序sortArr的元素存储的是初始化数组nums排序后的位置(即排序后在第几位

3.2.2遍历排序数组sortArr取元素方式不一样
基本计数排序主要是依次遍历排序数组sortArr,当其值非零时取元素并且该值减一,而优化计数排序主要是逆向遍历原始数组nums,通过在排序数组sortArr中找到原始数组nums每个元素的下标,而赋值给结果数组result

基本计数排序主要区别

 
 

在洛谷上,有很多适合用计数排序解决的问题,这里咱们挑几个典型的题目进行讲解。

虽然题目要求的是快速排序,但咱们可以用计数排序来“秀一把”。注意,这里只是为了展示计数排序的应用,实际比赛中还是要根据题目要求选择合适的算法哦

题目描述

给出n个数,找出这n个数的中位数,并将它们从小到大排序。

解题思路

  • 首先,用计数排序对数组进行排序。
  • 然后,根据排序后的数组直接找到中位数。

C++代码实现

 

注意:这里的代码假设输入的n为奇数,直接取排序后数组的中间元素作为中位数。如果n为偶数,可以根据题目要求取中间两个数的平均值或其他处理方式。


通过今天的讲解,我们不仅了解了计数排序的基本信息、原理和实现方法,还通过洛谷上的例题看到了它在解决实际问题中的潜在应用(尽管有时不是直接应用)。计数排序以其简洁高效的特点,在特定场景下(如数据范围较小)能够发挥巨大作用。希望大家能够掌握这一算法,并在实际编程中灵活运用它。


    以上就是本篇文章【计数排序:数不尽的奇妙与高效】的全部内容了,欢迎阅览 ! 文章地址:https://sicmodule.kub2b.com/news/12466.html
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 企库往资讯移动站 https://sicmodule.kub2b.com/mobile/ , 查看更多   
最新文章
发改委:推进户用光伏发展,助力农民拓宽增收新路径
中国产品流通经纪人协会供销合作行业标准《农产品食品供应商信用评价规范》参编单位征集函中国农产品流通经纪人协会供销合作行业
泉州百度爱采购运营介绍
百度爱采购入驻条件有哪些:商家需持有工商行政管理局颁发的营业执照,并且执照在6个月有效期内;厂家商品真实在营且符合国家相
抖音feed是什么 feed广告投放流程
feed是什么?feed流(又称信息流)它是穿插在App内容中的广告,具有原生沉浸式体验,支持多种展现形式。feed可以进行线索收集,
抖音投流怎么投?找到最合适的优化路线,实现精准引流与高效转化!
在如今竞争激烈的市场中,抖音广告已经成为商家吸引流量、增加曝光和转化的重要工具。很多企业都在问:“抖音投流怎么投,才能真
提升脸书播放/浏览量:Facebook Workplace的策略
以下介绍:提升脸书播放/浏览量:Facebook Workplace的策略关于提升脸书播放/浏览量:Facebook Workplace的策略所提到的问题请大
想换07年左右的老车,值得吗?
百车全说别人研究车,而我研究你!问:想买一辆2007年左右,绿色(丨), 3.0。主要是喜欢这种雪茄车身,想留着自己偶尔开一下,家
年度盘点丨西安:2024年度十大交通精细化治理案例
​​2024年,西安公安交警深入践行以人民为中心的发展思想,聚焦群众反映强烈的交通问题,坚持缓堵保畅、全域治理,坚持小切口入
怎样才能很好的提高百度SEO的排名呢
怎样使自己的网站在百度等搜索引擎排名靠前  提高用户体验确保网站加载速度快,移动设备友好,并提供良好的用户互动体验。利用
《人工智能:未来世界的“智慧引擎”》
在当今这个科技飞速发展的时代,人工智能(Artificial Intelligence,简称AI)正以前所未有的速度重塑
未来直播技术的创新与发展方向
随着信息技术的快速发展和移动互联网的广泛普及,直播已经成为当今互联网领域的重要应用之一。从最初的娱乐直播到现在的教育直播