计数排序的实现--适用于元素均较小的seq
今天无聊就打算把所有的排序算法都看一遍。。。
- 计数排序的时间复杂度是O(n),在算法导论中,用决策树模型中论证了,比较排序的情况为nlogn的复杂度。而计数排序的时间复杂度小于他的原因就是它不需要进行比较。
- 计数排序的原理就是根据原数组(A)里面最大的元素来一个与其一样大的数组(B),新开的数组(B)的第 i 个元素的值就是 i 在原数组(A)里面出现的次数.这样就可以根据新开的数组(B)来确定原数组(A)的排序。
我们先来看看排序部分的实现:(len是数组的长度)
void countSort(int *arrayL, int len) {
int findMax = 0;
for (int i = 0; i != len; i++)
if (findMax < arrayL[i])
findMax = arrayL[i];
findMax += 1; //元素应该是从 1 开始,而数组下标是从 0 开始,所以加 1
int *sortArray = new int[findMax]; //开始设定每个元素出现的次数都为 0
for (int i = 0; i != findMax; i++)
sortArray[i] = 0; //当对应的元素出现时,个数加 1
for (int i = 0; i != len; i++)
++sortArray[arrayL[i]]; //排序
int count = 0;
for (int i = 0; i != len; i++) {
for (int j = count; j != findMax; j++) {
count++; // sortArray 中在 count 前面的元素已经遍历过了
if (sortArray[j] != 0) {
//这里 for 循环是当出现元素个数不为 1 的情况时
for (int k = 0; k != sortArray[j]; k++) {
arrayL[i++] = j; //将元素的值赋到原数组
}
i--; //for 循环里面还会自增
break;
}
}
}
}
这部分的代码应该不难理解,因为基本都已经在代码注释说明了。这里原理就是,新开的数组的下标就是原数组的元素值。这样的话,当新开的数组某下标对应的值不为 0 时,代表该下标值在原数组出现过,而我们知道下标是有序的,那么就可以在遍历新建数组的时候有序地将有在原数组出现过的值赋给原数组。这样原数组就变得有序了。
但根据这个算法的实现我们可以看出,它并不适合当数组的元素值很大的时候。因为这样的话新开的数组空间很大,当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k),那么当K很大时,新开数组太大,既浪费空间,时间上也会有很大开销,因为虽然看上去是Θ(n + k),但当k很大时时间还是很长的。所以当需要排序的数组的元素值均在0~100之间时会比较适合。特别是当有很多元素重复的时候。另外,对于浮点数,字符串的排序他也无能为力。
其实,还有一个地方用这个算法的话会比较好,那就是在基数排序中比较每个位数的时候,因为每位数都是在0~9之间,用这个算法就很perfect了。。。
计数排序的实现--适用于元素均较小的seq的更多相关文章
- 计数排序(counting-sort)——算法导论(9)
1. 比较排序算法的下界 (1) 比较排序 到目前为止,我们已经介绍了几种能在O(nlgn)时间内排序n个数的算法:归并排序和堆排序达到了最坏情况下的上界:快速排序在平均情况下达到该上界. ...
- JavaScript 数据结构与算法之美 - 桶排序、计数排序、基数排序
1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算 ...
- 排序算法的C语言实现(下 线性时间排序:计数排序与基数排序)
计数排序 计数排序是一种高效的线性排序. 它通过计算一个集合中元素出现的次数来确定集合如何排序.不同于插入排序.快速排序等基于元素比较的排序,计数排序是不需要进行元素比较的,而且它的运行效率要比效率为 ...
- C语言-计数排序
计数排序的基本思想是:统计一个数序列中小于某个元素a的个数为n,则直接把该元素a放到第n+1个位置上.当然当过有几个元素相同时要做适当的调整,因为不能把所有的元素放到同一个位置上.计数排序假设输入的元 ...
- 20191104-基于Python计数排序算法分析
计数排序 计数排序算法没有用到元素间的比较,它利用元素的实际值来确定它们在输出数组中的位置,也就是说元素从未排序状态变为已排序状态的过程,是由额外空间的辅助和元素本身的值决定的,将每个元素出现的次数记 ...
- 计数排序和桶排序(Java实现)
目录 比较和非比较的区别 计数排序 计数排序适用数据范围 过程分析 桶排序 网络流传桶排序算法勘误 桶排序适用数据范围 过程分析 比较和非比较的区别 常见的快速排序.归并排序.堆排序.冒泡排序等属于比 ...
- 计数排序(Count Sort )与插入排序(Insert Sort)
计数排序法:计数数组适用于当前数组密集的情况.例如(2,3,5,4,2,3,3,2,5,4) 方法:先找出最大值最小值,之后统计每个数出现的次数,根据次数从小到大往数组里添加 计数排序法是一种不需要比 ...
- 归并排序 & 计数排序 & 基数排序 & 冒泡排序 & 选择排序 ----> 内部排序性能比较
2.3 归并排序 接口定义: int merge(void* data, int esize, int lpos, int dpos, int rpos, int (*compare)(const v ...
- 《algorithms Unlocked》读书笔记3——计数排序
<Algorithms Unlocked>是 <算法导论>的合著者之一 Thomas H. Cormen 写的一本算法基础,算是啃CLRS前的开胃菜和辅助教材.如果CLRS的厚 ...
随机推荐
- 《转》玩转图片Base64编码
引言 图片处理在前端工作中可谓占据了很重要的一壁江山.而图片的 base64 编码可能相对一些人而言比较陌生,本文不是从纯技术的角度去讨论图片的 base64 编码.标题略大,不过只是希望通过一些浅显 ...
- spring任务执行器与任务调度器(TaskExecutor And TaskScheduler)
对于多线程及周期性调度相关的操作,spring框架提供了TaskExecutor和TaskScheduler接口为异步执行和任务调度.并提供了相关实现类给开发者使用.(只记录采用注解的使用形式,对于X ...
- POJ3421:X-factor Chains——题解
http://poj.org/problem?id=3421 题目大意:一个数列,起始为1,终止为一给定数X,满足Xi < Xi+1 并且Xi | Xi+1. 求出数列最大长度和该长度下的情况数 ...
- CF527A:Playing with Paper——题解
https://vjudge.net/problem/CodeForces-527A http://codeforces.com/problemset/problem/527/A 题目大意:一个纸长a ...
- JavaScript倒计时脚本
JavaScript倒计时在Web中用得非常广泛,比如常见的团购啊.还有什么值得期待的事情,都可以用到倒计时.现在举了四个例子,比如时间长的倒计时,小时倒计时,最简的倒计时,还有秒表等等,应该可以满足 ...
- luncence
问题的提出: 我们在访问淘宝,京东这些商城系统的时候,我们可以随意的在文本框输入关键字就可以获取到所想要的信息或者相关的信息,那么我们到底是如何实现这个功能的呢,为什么可以随意的输入就可以显示相关的信 ...
- Leetcode 381. O(1) 时间插入、删除和获取随机元素 - 允许重复
1.题目描述 设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构. 注意: 允许出现重复元素. insert(val):向集合中插入元素 val. remove(val):当 va ...
- HDU1298 字典树+dfs
T9 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submissi ...
- Redis(3) 配置文件 redis.conf
Redis.conf 配置详解: # Redis configuration file example. # # Note that in order to read the configuratio ...
- 【PHP】Windows下配置用mail()发送邮件
ZZ:解决windows系统下php.ini邮件配置正确不发送邮件的问题 php mail()函数在windows不能用,需要安装sendmail,假如是用的XAMPP,则已经下载好,不需要重新下载~ ...