云漫圈 | 计数排序,你真的了解么?

640?wx_fmt=jpeg

参加 2018 AI开发者大会,请点击 ↑↑↑

640?wx_fmt=jpeg


640?wx_fmt=jpeg



—————  第二天  —————



640?wx_fmt=jpeg


640?wx_fmt=jpeg



640?wx_fmt=jpeg


640?wx_fmt=jpeg


640?wx_fmt=jpeg


640?wx_fmt=jpeg


640?wx_fmt=jpeg



————————————



640?wx_fmt=jpeg

640?wx_fmt=jpeg


640?wx_fmt=jpeg



640?wx_fmt=jpeg


640?wx_fmt=jpeg



640?wx_fmt=jpeg


640?wx_fmt=jpeg


640?wx_fmt=jpeg


640?wx_fmt=jpeg



640?wx_fmt=jpeg




640?wx_fmt=png


假定20个随机整数的值如下:


9,3,5,4,9,1,2,7,8,1,3,6,5,3,4,0,10,9 ,7,9


如何给这些无序的随机整数排序呢?


非常简单,让我们遍历这个无序的随机数列,每一个整数按照其值对号入座,对应数组下标的元素进行加1操作。


比如第一个整数是9,那么数组下标为9的元素加1:


640?wx_fmt=png


第二个整数是3,那么数组下标为3的元素加1:


640?wx_fmt=png


继续遍历数列并修改数组......


最终,数列遍历完毕时,数组的状态如下:


640?wx_fmt=png


数组每一个下标位置的值,代表了数列中对应整数出现的次数。


有了这个“统计结果”,排序就很简单了。直接遍历数组,输出数组元素的下标值,元素的值是几,就输出几次:


0,1,1,2,3,3,3,4,4,5,5,6,7,7,8,9,9,9,9,10


显然,这个输出的数列已经是有序的了。




640?wx_fmt=jpeg


640?wx_fmt=jpeg


640?wx_fmt=jpeg




  1. public static int[] countSort(int[] array) {



  2.    //1.得到数列的最大值



  3.    int max = array[0];



  4.    for(int i=1; i<array.length; i++){



  5.        if(array[i] > max){



  6.            max = array[i];



  7.        }



  8.    }



  9.    //2.根据数列最大值确定统计数组的长度



  10.    int[] countArray = new int[max+1];



  11.    //3.遍历数列,填充统计数组



  12.    for(int i=0; i<array.length; i++){



  13.        countArray[array[i]]++;



  14.    }



  15.    //4.遍历统计数组,输出结果



  16.    int index = 0;



  17.    int[] sortedArray = new int[array.length];



  18.    for(int i=0; i<countArray.length; i++){



  19.        for(int j=0; j<countArray[i]; j++){



  20.            sortedArray[index++] = i;



  21.        }



  22.    }



  23.    return sortedArray;



  24. }








  25. public static void main(String[] args) {



  26.    int[] array = new int[] {4,4,6,5,3,2,8,1,7,5,6,0,10};



  27.    int[] sortedArray = countSort(array);



  28.    System.out.println(Arrays.toString(sortedArray));



  29. }



这段代码在一开头补充了一个步骤,就是求得数列的最大整数值max。后面创建的统计数组countArray,长度就是max+1,以此保证数组的最后一个下标是max。



640?wx_fmt=jpeg


640?wx_fmt=jpeg



640?wx_fmt=jpeg



95,94,91,98,99,90,99,93,91,92



640?wx_fmt=jpeg



怎么解决这个问题呢?


很简单,我们不再以(输入数列的最大值+1)作为统计数组的长度,而是以(数列最大值和最小值的差+1)作为统计数组的长度。


同时,数列的最小值作为一个偏移量,用于统计数组的对号入座。


以刚才的数列为例,统计数组的长度为  99-90+1 = 10 ,偏移量等于数列的最小值 90 。


对于第一个整数95,对应的统计数组下标是 95-90 = 5,如图所示:



640?wx_fmt=png



640?wx_fmt=jpeg



640?wx_fmt=jpeg



什么意思呢?让我们看看下面的例子:


640?wx_fmt=png


给定一个学生的成绩表,要求按成绩从低到高排序,如果成绩相同,则遵循原表固有顺序。


那么,当我们填充统计数组以后,我们只知道有两个成绩并列95分的小伙伴,却不知道哪一个是小红,哪一个是小绿:


640?wx_fmt=png



640?wx_fmt=jpeg



640?wx_fmt=jpeg



下面的讲解会有一些烧脑,请大家扶稳坐好。我们仍然以刚才的学生成绩表为例,把之前的统计数组变形成下面的样子:



640?wx_fmt=png


这是如何变形的呢?统计数组从第二个元素开始,每一个元素都加上前面所有元素之和。


为什么要相加呢?初次看到的小伙伴可能会觉得莫名其妙。


这样相加的目的,是让统计数组存储的元素值,等于相应整数的最终排序位置。比如下标是9的元素值为5,代表原始数列的整数9,最终的排序是在第5位。


接下来,我们创建输出数组sortedArray,长度和输入数列一致。然后从后向前遍历输入数列:


第一步,我们遍历成绩表最后一行的小绿:


小绿是95分,我们找到countArray下标是5的元素,值是4,代表小绿的成绩排名位置在第4位。


同时,我们给countArray下标是5的元素值减1,从4变成3,,代表着下次再遇到95分的成绩时,最终排名是第3。


640?wx_fmt=png



第二步,我们遍历成绩表倒数第二行的小白:


小白是94分,我们找到countArray下标是4的元素,值是2,代表小白的成绩排名位置在第2位。


同时,我们给countArray下标是4的元素值减1,从2变成1,,代表着下次再遇到94分的成绩时(实际上已经遇不到了),最终排名是第1。


640?wx_fmt=png



第三步,我们遍历成绩表倒数第三行的小红:


小红是95分,我们找到countArray下标是5的元素,值是3(最初是4,减1变成了3),代表小红的成绩排名位置在第3位。


同时,我们给countArray下标是5的元素值减1,从3变成2,,代表着下次再遇到95分的成绩时(实际上已经遇不到了),最终排名是第2。


640?wx_fmt=png



这样一来,同样是95分的小红和小绿就能够清楚地排出顺序了,也正因此,优化版本的计数排序属于稳定排序


后面的遍历过程以此类推,这里就不再详细描述了。



640?wx_fmt=jpeg


640?wx_fmt=jpeg



  1. public static int[] countSort(int[] array) {



  2.    //1.得到数列的最大值和最小值,并算出差值d



  3.    int max = array[0];



  4.    int min = array[0];



  5.    for(int i=1; i<array.length; i++) {



  6.        if(array[i] > max) {



  7.            max = array[i];



  8.        }



  9.        if(array[i] < min) {



  10.            min = array[i];



  11.        }



  12.    }



  13.    int d = max - min;



  14.    //2.创建统计数组并统计对应元素个数



  15.    int[] countArray = new int[d+1];



  16.    for(int i=0; i<array.length; i++) {



  17.        countArray[array[i]-min]++;



  18.    }



  19.    //3.统计数组做变形,后面的元素等于前面的元素之和



  20.    int sum = 0;



  21.    for(int i=0;i<countArray.length;i++) {



  22.        sum += countArray[i];



  23.        countArray[i] = sum;



  24.    }



  25.    //4.倒序遍历原始数列,从统计数组找到正确位置,输出到结果数组



  26.    int[] sortedArray = new int[array.length];



  27.    for(int i=array.length-1;i>=0;i--) {



  28.        sortedArray[countArray[array[i]-min]-1]=array[i];



  29.        countArray[array[i]-min]--;



  30.    }



  31.    return sortedArray;



  32. }





  33. public static void main(String[] args) {



  34.    int[] array = new int[] {95,94,91,98,99,90,99,93,91,92};



  35.    int[] sortedArray = countSort(array);



  36.    System.out.println(Arrays.toString(sortedArray));



  37. }




640?wx_fmt=jpeg



640?wx_fmt=jpeg



640?wx_fmt=jpeg


640?wx_fmt=jpeg



640?wx_fmt=jpeg


640?wx_fmt=jpeg


1.当数列最大最小值差距过大时,并不适用计数排序。


比如给定20个随机整数,范围在0到1亿之间,这时候如果使用计数排序,需要创建长度1亿的数组。不但严重浪费空间,而且时间复杂度也随之升高。


2.当数列元素不是整数,并不适用计数排序。


如果数列中的元素都是小数,比如25.213,或是0.00000001这样子,则无法创建对应的统计数组。这样显然无法进行计数排序。



640?wx_fmt=jpeg


640?wx_fmt=jpeg

1.微信群:

添加小编微信:tangguoyemeng,备注“进群+姓名+公司职位”即可,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!


2.征稿:

投稿邮箱:lijy@csdn.net;微信号:tangguoyemeng。请备注投稿+姓名+公司职位。


推荐阅读


  • 为什么阿里飞猪、滴滴、携程都被质疑滥用大数据杀熟?

  • 程序员入错行怎么办?

  • 我们研究了1.5万场活动,换个大城市生活可能对你有用

  • 大数据揭秘: 原来单身女生有这些特点...

  • 放弃培训班自学编程,9 个月后我成为年薪 6 位数的软件工程师

  • 82岁的北大教授证明了黎曼猜想?

  • 继承变量覆盖及构造函数失配,竟然会导致这些漏洞

  • 35岁IT老兵,转型AI,我做错了吗?

640?wx_fmt=jpeg


↓↓↓  点击【阅读原文】查看「CSDN云计算」往期精彩内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/525406.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BugkuCTF-MISC题blind_injection

下载附件 方法一&#xff1a; 下载用wireshark打开 题目说的是盲注&#xff0c;而注入一般都是走的http&#xff0c;直接导出http对象&#xff0c;再根据大小排序 得到flag 方法二&#xff1a; 若HTTP对象列表点击大小无反应 将其导出&#xff0c;命名为output 在文件夹里查…

ubuntu服务器ssh登录密码修改,Ubuntu-18.04 下修改root用户密码,安装SSH服务,允许root用户远程登录,安装vsftp服务器...

修改root用户密码打开终端&#xff0c;输入 sudo passwd root 指令&#xff1a;安装SSH服务ssh默认端口号是22&#xff0c;可以在/etc/ssh/sshd_config文件中修改查看服务器否开启&#xff1a;netstat -tlp启动服务&#xff1a;sudo /etc/init.d/ssh start重启服务&#xff1a;…

Python json模块 - Python零基础入门教程

目录 一.前言二.python json 模块常用函数三.json 转 Python 字典 dict四.Python 字典 dict 转 json五.关于 json.dump 和 json.load六.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 >> Python 基础入门 一.前言 JSON 的全称是 JavaScript Object Notation&…

Cloud一分钟 | 英国发布大规模遗传数据;德国电信与华为联合发布PLAS云连接服务...

Hello&#xff0c;everyone&#xff1a;10月15日早&#xff0c;星期一&#xff0c;祝大家工作愉快&#xff01;一分钟新闻时间&#xff1a;★ 百度云与智慧农业的头部企业强强联合&#xff0c;共建ABC智能农业生态。★ 德国电信与华为联合发布PLAS云连接服务。★ 英国发布大规模…

“汉堡+奶昔”怎么就成了精致生活的热门标签?

图片来源&#xff1a;视觉中国文章来源&#xff1a;DT财经“左手汉堡&#xff0c;右手奶昔&#xff0c;这是新天地Coco的时髦新日常。最近沪上刮起一阵打卡新风潮&#xff0c;汉堡竟然成了标记城市美好生活的一大利器。还在纠结晚餐去金拱门还是汉堡王的DT君&#xff0c;发现自…

揭开互联网公司的神秘面纱,数据解读那些slay整个行业的互联网公司

前言&#xff1a;随着互联网行业的日益兴盛&#xff0c;吸引力越来越多的牛人加入其中&#xff0c;也有许多小伙伴跃跃欲试&#xff0c;想要在互联网的浪潮中大展身手。今天我们通过看准网的数据&#xff0c;帮助大家对各大互联网公司有一个比较概括的了解。01.数据来源看准网提…

Cloud一分钟 | Gartner发布2018年第二季度全球服务器市场报告;中信银行联合腾讯云推出手机银行智能语音产品...

Hello&#xff0c;everyone&#xff1a;10月16日早&#xff0c;星期二&#xff0c;祝大家工作愉快&#xff01;一分钟新闻时间&#xff1a;完1.微信群&#xff1a;添加小编微信&#xff1a;tangguoyemeng&#xff0c;备注“进群姓名公司职位”即可&#xff0c;加入【云计算学习…

Cloud一分钟 | 华为云发布云数据安全白皮书;OPPO携手阿里云举行天池OGeek算法挑战赛...

Hello&#xff0c;everyone&#xff1a;10月17日早&#xff0c;星期三&#xff0c;祝大家工作愉快&#xff01;一分钟新闻时间&#xff1a;完1.微信群&#xff1a;添加小编微信&#xff1a;tangguoyemeng&#xff0c;备注“进群姓名公司职位”即可&#xff0c;加入【云计算学习…

关于这道填空题,你会如何回答?(附带学习链接)

曾经有一篇百万阅读量的爆文&#xff0c;里面出了道填空题&#xff0c;问&#xff1a;____是铜牌&#xff0c;____是银牌&#xff0c;____是金牌&#xff0c;____是王牌。小白的答案是&#xff1a;Java是铜牌&#xff0c;Linux是银牌&#xff0c;Hadoop是金牌&#xff0c;大数据…

BugkuCTF-Crypto题affine

题目描述&#xff1a; 这题考的是仿射密码&#xff0c;了解一下仿射密码 仿射密码为一类替换密码。它是一个字母对一个字母的。它的加密函数为 其a和m互质&#xff0c;m为字母的数目。 解码函数为 其a^-1为a在Zm群的乘法逆元 乘法逆元&#xff1a; 所有与26互素元素的乘法…

Python set集合 - Python零基础入门教程

目录 一.set 集合简介二.set 集合常用函数三.set 集合运算符四.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 >> Python 基础入门 在 Python 变量中除了以前文章所提到的整形 int / 浮点数 float / 布尔值 bool / 列表 list / 字典 dict 之外&#xff0c;还有…

Cloud一分钟 | 华为云、腾讯云、阿里云中标「央视2018年租赁公有云服务」项目...

Hello&#xff0c;everyone&#xff1a;10月18日早&#xff0c;星期四&#xff0c;祝大家工作愉快&#xff01;一分钟新闻时间&#xff1a;完1.微信群&#xff1a;添加小编微信&#xff1a;tangguoyemeng&#xff0c;备注“进群姓名公司职位”即可&#xff0c;加入【云计算学习…

Cloud一分钟 | 华云数据中标上药控股私有云千万级项目; 总投资90亿元的中国移动厦门数据中心,一期电源工程项目候选人公示...

Hello&#xff0c;everyone&#xff1a;10月19日早&#xff0c;星期五&#xff0c;祝大家工作愉快&#xff01;一分钟新闻时间&#xff1a;完1.微信群&#xff1a;添加小编微信&#xff1a;tangguoyemeng&#xff0c;备注“进群姓名公司职位”即可&#xff0c;加入【云计算学习…

Python set list dict tuple 区别和相互转换 - Python零基础入门教程

目录 一.前言二.Python set list dict tuple 区别三.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 >> Python 基础入门 一.前言 Python 提供多种数据类型来存放数据项集合&#xff0c;主要包括序列&#xff08;列表 list 和元组 tuple&#xff09;&#xff…

2023RT-Thread开发者大会

参加了一次RT-Thread的开发者大会&#xff0c;相当有意思&#xff0c;虽然一天奔波挺累&#xff0c;但睡了半天之后简单剪了下22号的视频&#xff0c;也就有时间写自己的参会笔记了。 与openEuler社区不同&#xff0c;RT-Thread社区更专注于嵌入式&#xff0c;与硬件厂商结合较…

企业大咖教你解决Kubernetes的挑战

Kubernetes&#xff08;K8s&#xff09;是自动化容器操作的开源平台&#xff0c;这些操作包括部署&#xff0c;调度和节点集群间扩展。如果你曾经用过Docker容器技术部署容器&#xff0c;那么可以将Docker看成Kubernetes内部使用的低级别组件。Kubernetes还可以提供容器弹性&am…

Android 之父裁员 30%:开发者如何避免“被离职”?

近几个月来&#xff0c;Google 和 Android 都不太太平。从 7 月 Google 被欧盟处以 50 亿美元的反垄断罚款&#xff0c;到引起恐慌的 Android 碎片化漏洞&#xff0c;再到 Android 的许可政策遭遇更改......而现在&#xff0c;由 Android 之父一手创立的初创公司也惨遭“滑铁卢…

面趣 | 据说这道烧脑的微软面试题很奇葩,你来试试?

参加 2018 AI开发者大会&#xff0c;请点击 ↑↑↑问面试题目&#xff1a;昨天&#xff0c;我早上8点爬山&#xff0c;晚上8点到山顶。睡了一觉后&#xff0c;今天&#xff0c;我早上8点从山顶原路下山&#xff0c;晚上8点到山脚。请问&#xff0c;有没有一个时刻&#xff0c;昨…

Cloud一分钟 | 苹果更新“隐私页面”;中国联通大数据正式升级,进入数智新阶段...

Hello&#xff0c;everyone&#xff1a;10月22日早&#xff0c;星期一&#xff0c;祝大家工作愉快&#xff01;一分钟新闻时间&#xff1a;完1.微信群&#xff1a;添加小编微信&#xff1a;tangguoyemeng&#xff0c;备注“进群姓名公司职位”即可&#xff0c;加入【云计算学习…

“双十一”即将来临,先来看看快递物流企业的大数据

继中通、韵达后&#xff0c;圆通速递于日前宣布涨价。据悉&#xff0c;圆通速递将对全国各网点到达上海地区的快件派送费上调&#xff0c;上调幅度为0.5元/票。双十一临近&#xff0c;快递企业接连涨价&#xff0c;行业或将迎来集体涨价潮。据圆通速递称&#xff0c;此次调价行…