计数排序和稳定的计数排序
计数排序不是基于元素比较,而是利用数组下标来确定元素的正确位置。计数排序是一个稳定的排序算法。当输入的元素是 n 个 0到 k 之间的整数时,时间复杂度是O(n+k),空间复杂度也是O(n+k),其排序速度快于任何比较排序算法。当k不是很大并且序列比较集中时,计数排序是一个很有效的排序算法。
算法思路
计数排序的算法思路是定义一个大小为序列最大值-最小值的大小的数组,遍历每一个元素,将其映射到数组中,例如最大值和最小值相差10,就定义一个大小为10的数组,每一个整数按照其值对号入座,对应数组下标的元素进行加1操作。
比如第一个整数是9,那么数组下标为9的元素加1:
最终,数列遍历完毕时,数组中的每一个值,代表了数列中对应整数的出现次数。有了这个统计结果,排序就很简单了,直接遍历数组,输出数组元素的下标值,元素的值是几,就输出几次。
不稳定的计数排序
算法的实现可以分为三个步骤
- 第一步 定义最大值和最小值,和一个最后添加会原来数组的下标index,然后遍历输入的序列,找到最大值和最小值赋值给max和min。
public int[] countingSort(int[] array){int index = 0;int min = array[1];int max = array[1];for (int i:array) {if (i>max){max = i;}if (i<min){min = i;}}
- 第二步 定义一个大小为max-min+1大小的数组,遍历序列将序列中的每一个元素减去min,将其映射到数组下标中,如果有相同的元素,则++;
int[] list = new int[max-min+1];for (int i:array){list[i-min]++;}
- 第三步 遍历临时储存的list数组,当list[i]的大小不等于0,即还有元素,将其赋给原数组array,注意这里的赋值是i+min而不是list[i+min]。
for (int i = 0; i < list.length; i++) {while (list[i]>0){array[index++] = i+min;list[i]--;}}return array;}
稳定的计数排序
稳定的基数排序跟上者的差别是在,如果值相同,则遵循原表固有顺序。
算法思路
算法的具体思路是在遍历完序列映射到数组中后,例如下图是已经映射好的数组。原序列为{90,99,95,95,94}
在第二个下标开始,加上前面元素的和,例如上图第一个下标为1,那么第二个下标的数值就为本身的0加上前面的1等于1。第三个就等于第三加上前面的数的总个数,以此类推。
这个数值其实就代表了映射的元素在原数组中因该在的位置,整个数组中有用的下标就只有0,4,5,9四个下标是由代表有数值的,其他都是空的,下标为0的数值为1即使第一个数字,下标为4的数值为2即第二个数,下标为5的数值为4,我们看到95是有两个数,所以是第3的数和第4的数,最后一个为第五的数。
理解了上面后,在赋值给原数组的过程中,从后往前遍历,例如原序列为{90,99,94,95,95},第一个数为95,在映射的数组中下标为4,即原数组array[4]=95,然后4-1=3,即如果有第二个95,它的位置就是3,然后第二个数是95,这时候下标为3,即array[3]=95,依照这种算法随后得到的结果就为{90,94,95,95,99},而且是稳定的排序。
代码的实现分为两步
第一步在得到了映射后的数组countArray后,从第二个下标开始,加上前面的数的个数,即countArray[i] = countArray[i-1]+countArray[i]。
for (int i = 1; i < countArray.length; i++) {countArray[i] = countArray[i-1]+countArray[i];}
第二步是定义一个数组用于存储,countArray[i-min]即映射数组的值,即第几个元素,例如第5个元素,那么下标就为4,所以要-1,然后countArray[i-min]自减。
int[] sortArray = new int[array.length];for (int i:array){sortArray[countArray[i-min]-1] = i;countArray[i-min]--;}
计数排序和稳定的计数排序相关推荐
- 排序算法 - 面试中的排序算法总结
排序算法总结 查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中.因为其实现代码较短,应用较常见.所以在面试中经常会问到排序算法及其相关的问题.但万变不离其宗,只要熟悉了思想,灵活运用也不 ...
- 排序专题之 各个内外排序算法的比较
1.稳定性比较 插入排序.冒泡排序.二叉树排序.二路归并排序及其他线形排序是稳定的 选择排序.希尔排序.快速排序.堆排序是不稳定的 2.时间复杂性比较 插入排序.冒泡排序.选择排序的时间复杂性为O(n ...
- 程序员内功修炼之学好算法和数据结构(一)排序基础、选择排序、插入排序、希尔排序...
一.排序基础(重要) 1.1 为什么要学习O(n^2)的排序算法? 编码简单,易于实现,是一些简单情景的首选. 在一些特殊情况下,简单的排序算法更有效. 简单的排序算法思想衍生出复杂的排序算法,在这个 ...
- 计数排序,基数排序,桶排序
转 http://blog.163.com/yuyang_tech/blog/static/216050083201382055821953/ 与合并排序,堆排序,快速排序等基于比较的排序算法不同,计 ...
- 排序算法之计数排序、基数排序和桶排序
转自:http://www.cnblogs.com/ttltry-air/archive/2012/08/04/2623302.html 计数排序,基数排序,桶排序等非比较排序算法,平均时间复杂度都是 ...
- java sorted排序_【算法】排序算法之计数排序
前几回,我们已经对冒泡排序.直接插入排序.希尔排序.选择排序.快速排序.归并排序.堆排序做了说明分析.本回,将对计数排序进行相关说明分析. 一.排序算法系列目录说明 冒泡排序(Bubble Sort) ...
- 【算法学习】线性时间排序-计数排序、基数排序和桶排序详解与编程实现
计数排序 计数排序假设n个输入元素中的每一个都是介于0到k之间的整数.此处k为某个整数(输入数据在一个小范围内). 算法思想 计数排序的基本思想是对每一个输入元素x,确定出小于x的元素的个数.然后再将 ...
- ❤️万字总结八大排序:冒泡排序,选择排序,插入排序,堆排序,希尔排序,归并排序,计数排序❤️
目录 主要排序算法性能对比 冒泡排序 选择排序 插入排序 堆排序 希尔排序 快速排序 Hoare版 挖坑版 前后指针法 归并排序 计数排序 海量数据的排序问题 主要排序算法性能对比 冒泡排序 各位同学 ...
- c++ 二维数组 排序_【算法】排序算法之计数排序
前几回,我们已经对[算法]排序算法之冒泡排序.[算法]排序算法之插入排序.[算法]排序算法之希尔排序.[算法]排序算法之选择排序.[算法]排序算法之快速排序.[算法]排序算法之归并排序.[算法]排序算 ...
最新文章
- linux防火墙伦堂,「linux专栏」自从看了这篇文章,我彻底搞懂了selinux和防火墙...
- 如何进行高效的时间管理?
- spark数据查询语句select_sparksql语句
- php.ini 中文版第二部分(关于这个配制文件)
- ajax 载入html后不能执行其中的js解决方法
- java 内部类怎么new_[转]【Java】内部类(Inner Class)如何创建(new)
- spring-boot 入门学习
- Rabbitmq消息发送事务与确认机制
- javascript --- 作用域和闭包
- HH SaaS电商系统的销售订单毛利润模块设计
- 在读博士一作发Nature,学校重奖50万!
- 前端实习生笔试_前端实习生面试题——HTML
- 4-1 :input表单选择器 jQuery第四章 很关键 好像 刚好可以解决 微信自动回复...
- 利用VMware Infrastructure SDK编程控制虚拟机集群(2)
- 《『若水新闻』客户端开发教程》——16.添加广告
- 实用干货!大数据入门的常用技术栈全在这里了
- WebWork深入浅出(http://www.blogjava.net/moxie/archive/2006/10/20/76375.html)
- 专访许鹏:谈C程序员修养及大型项目源码阅读与学习
- 郭敬明最经典的45句话
- Vue路由守卫(导航守卫)及使用场景
热门文章
- NaN 是什么?它的类型是什么?如何可靠地测试一个值是否等于 NaN ?
- oracle中怎么自定义函数,Oracle自定义函数
- Canvas绘制炫酷的火焰风暴动画
- Imatest 崩溃
- 小米max2怎么获得sn与imei验证手机真伪
- Pytorch 文本数据分析方法(标签数量分布、句子长度分布、词频统计、关键词词云)、文本特征处理(n-gram特征、文本长度规范)、文本数据增强(回译数据增强法)
- 如何离线查看22.3TB全国高清谷歌卫星影像
- mysql实现记事本_记事本 __ 数据库
- Redis开发和运维相关shell命令总结
- 黑客讲故事:攻下隔壁女生路由器后,我都做了些什么~