[一周一算法]算法导论学习之计数排序

  计数排序是一种线性时间的排序,同时也是一种非比较排序

  代码如下:

 1 void CountingSort(int *data, int k, int num)  // A ~ data[], B ~ aimArray[], C ~ tempArray[]
 2 {
 3     int *aimArray = new int[num];
 4     int *tempArray = new int[k + 1];
 5     for (int i = 0; i <= k; i++)
 6         tempArray[i] = 0;
 7     for (int j = 0; j < num; j++)
 8         tempArray[data[j]]++;
 9     for (int i = 1; i <= k; i++)
10         tempArray[i] = tempArray[i] + tempArray[i - 1];11     for (int j = num - 1 ; j >= 0; j--)
12     {
13         aimArray[tempArray[data[j]]] = data[j];
14         tempArray[data[j]]--;
15     }
16     for (int i = 0; i < num; i++)
17         data[i] = aimArray[i + 1];
18 }

排序例图如下:

计数排序需要用到三个数组 :

代码中 数组data[A]是待排序数组,aimArray[B]是中间数组, tempArray[C]是保存数组元素相对位置的数组

5-6行,将tempArray数组清零

7-10行, 将原数组元素相对关系储存起来, 如图中原数组{2,5,3,0,2,3,0,3} 再对照储存后的tempArray数组,数组序号代表的是data数组拥有的元素,位置0的元素为2,意味着≤0的元素有两个,所以有两个零,重新定位的时候就应该将这两个0的位置定为 0和1,位置1的元素也为2,就是那两个0,所以原数组data中没有1。依次类推,在剩余的数组中将原数组data所有的元素定好位置再放入AimArray中,最后在转移回数组data中,就完成了计数排序

时间: 2024-10-12 01:07:39

[一周一算法]算法导论学习之计数排序的相关文章

常见的排序算法(四)( 归并排序,计数排序 , 基数排序)

 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并. (如果读者不太了解什么叫分治法,可以去看看<算法导论>第一二章.) 归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1:否则将第

算法——排序之计数排序

最近想到算法导论中的计数排序,看看理解的怎么样试着讲讲自己的理解. 1.思想: 计数排序 是 线性时间的 排序算法,时间复杂度为O(n),虽然有一定的局限性.但是还是很好的一种算法. 用2个数组进行额外的存储信息,数组 c[ ] 是对 数据中值相同的 记录下来,以便后面查阅:b[ ]是输出的有序数组,再将有序的数组输出. 2.范围: 计数排序是针对  在 一定取值范围 的 整数 数据.比如:a[ ]中 a[ i ]∈( 0 , 10 ). 3.代码: <span style="font-s

排序算法的c++实现——计数排序

任何比较排序算法的时间复杂度的上限为O(NlogN), 不存在比o(nlgN)更少的比较排序算法.如果想要在时间复杂度上超过O(NlogN)的时间复杂度,肯定需要加入其它条件.计数排序就加入了限制条件,从而使时间复杂度为O(N). 计数排序的核心思想(来自算法导论):计数排序要求待排序的n个元素的大小在[0, k]之间,并且k与n在一个数量级上,即k=O(n).对于每一个输入元素x, 确定小于等于x的个数为i.利用这一信息,就可以把元素x放到输出数组的正确位置,即把元素x放到输出数组下标为i-1

计数排序、基数排序与桶排序

一.计数排序 稳定. 当输入的元素是n 个小区间(0到k)内整数时,它的运行时间是 O(n + k),空间复杂度是O(n). const int K = 100; //计数排序:假设输入数据都属于一个小区间内的整数,可用于解决如年龄排序类的问题 //Input:A[0, ..., n-1], 0 <= A[i] < K //Output:B[0, ..., n-1], sorting of A //Aux storage C[0, ..., K) void CountSort(int A[],

【算法导论学习-014】计数排序(CountingSortTest)

参考:<算法导论>P194页 8.2节 Counting sort 1.Counting sort的条件 待排序数全部分布在0~k之间,且k是已知数:或者分布在min~max之间,等价于分布在0~max-min之间,max和min是已知数. 2.java 实现 /** * 创建时间:2014年8月17日 下午3:22:14 项目名称:Test * * @author Cao Yanfeng * @since JDK 1.6.0_21 类说明: 计数排序法,复杂度O(n), 条件:所有数分布在0

【算法导论-学习笔记】以线性时间增长的排序——计数排序

计数排序是一种能够达到运行时间能够线性时间θ(n)的排序算法.在排序算法里算是最快的算法之一,当然,他有很强烈的前提.下面开始介绍一下技术排序(Counting Sort). 算法思想 计数排序假设n个输入元素中的每一个都是介于0到k之间的整数,此处k为某个整数.这样可以用一个数组C[0..k]来记录待排序数组里元素的数量.当k=O(n)时,计数排序的运行时间为θ(n). 注:关于C[0..k],用键值对描述的话,待排序元素是键,相同元素的个数是值.例:待排序数组<2,3 , 6,4 , 1 ,

算法导论 学习资源

学习的过程会遇到些问题,发现了一些比较好的资源,每章都会看下别人写的总结,自己太懒了,先记录下别人写的吧,呵呵. 1  Tanky Woo的,每次差不多都看他的 <算法导论>学习总结 - 1.前言 <算法导论>学习总结 - 2.第一章 && 第二章 && 第三章 <算法导论>学习总结 - 3.第四章 && 第五章 <算法导论>学习总结 - 4.第六章(1) 堆排序 <算法导论>学习总结 - 5.第六

【算法导论学习-015】基数排序(Radix sort)

1.<算法导论>P197页 8.3节Radix sort 2.java实现 这里仅仅对[算法导论学习-014]计数排序 的参数进行了修改,同时仅仅修改了一行代码. /** * 创建时间:2014年8月17日 下午4:05:48 * 项目名称:Test * @author Cao Yanfeng * @since JDK 1.6.0_21 * 类说明: 利用计数排序实现基数排序 * 条件:待排序的所有数位数相同,注意,即便不相同,也可以认为是最多那个位数,如下面的例子可以认为都是3位数 */ p

算法导论学习---红黑树具体解释之插入(C语言实现)

前面我们学习二叉搜索树的时候发如今一些情况下其高度不是非常均匀,甚至有时候会退化成一条长链,所以我们引用一些"平衡"的二叉搜索树.红黑树就是一种"平衡"的二叉搜索树,它通过在每一个结点附加颜色位和路径上的一些约束条件能够保证在最坏的情况下基本动态集合操作的时间复杂度为O(nlgn).以下会总结红黑树的性质,然后分析红黑树的插入操作,并给出一份完整代码. 先给出红黑树的结点定义: #define RED 1 #define BLACK 0 ///红黑树结点定义,与普通