计数排序算法小记

计数排序是排序算法的一种,冒泡、插入、选择、快排等都是非常经典、妙不可言的排序算法,下面来记录一笔关于计数排序的故事。

因为对于我个人理解来说,算法是一门比较烧脑的学科,所以我总是想借用某些实际的场景来说明问题,这样不但自己记的牢,也能

给读者一种轻松的心情。不知道大家是否印象中还有这么一段音响:

这次我们班月考的总成绩排名如下:“雷军、张亚勤并列第1名,张朝阳、李彦宏、马化腾并列第3名,任正非第6名......,马云倒数第一....”,好了,风趣归风趣,言归正传,这里我们抽象出一个这样的模型来:
当A、B并列第一名的时候,需要占据2个名次,所以接下来只能从第(1+2)名开始,而当C、D、E并列第3名的时候,又要占据3个坑,所以接下来又只能从第(3+3)名开始,可以发现,每个人的名次其实和两个因素相关,那就是:

1.上一个人的名次

2.上一个名次的人数

一旦知道以上两个元素,每个人的名次也就确定了,那么它在班级里相应的成绩位置也就确定了;

这里的计数排序的原理其实就如同上面的排名一样,“计数”可以理解为是“计算个数”,那么计算什么个数呢,当然是计算相同成绩的人的个数啦,那么我们就对以下的这张成绩单来排个序吧:

「任正非:85分   雷军:99分   张朝阳:90分   马云:72分   李彦宏:90分   张亚勤:99分    马化腾:90分」

首先,以我们最熟悉的方式来把上面的分数抽象到我们的数组中:

[85,99,90,72,90,99,90]

下面我们先来看看把成绩相同的给抽取出来,只需要以O(n)的时间复杂度遍历一边即可,

我们发现得90分的有3个人,得99分的有2个人,得85分的有1个人,而得72分的也有1个人,这时候我们先把抽取出来的数据保存下来,

这里可以巧妙一点,我们再建一个数组array,用分数作为数组的下标,而取得相应分数的人的个数作为数组的值,就成为以下的形式:

        [....................................... 1 ..............1 .........3..............2..............................................]

下标:0 1 2 3 4 5...................72 ...........85........90............99.............................................

好了,我们的第二轮数据也已经出来了,这时候你发现,其实我们新建的这个数组array中大部分都是空的,只用到了极少数的空间,

其实到这里你已经可以发现,各个人的位置也已经确定下来了,72分的有一位,显然排在第1个位置,而85分的也有1位,那就排在第

(1+1=2)的位置,而90分的人有3个,所以需要3个位置,所以要排到(1+1+3=5)的位置,99的有两位,所以要排到(1+1+3+2=7)的位置

所以依次如下放置就行:

 【1     2】      【3,4,5】     【6,7】

   72   85                95               99

好了,基本的思路已经出来,具体的算法以及写法每个人都各异,最关键的还是在于“计数”这个思想,以成绩排名这个例子来做场景,也只是为了能够让人更加快得感受到这种算法的妙处。

PS:如果阁下有比较好的理解与建议,还请留下一言半句,多谢多谢!

 

转载于:https://my.oschina.net/u/3784034/blog/2249664

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值