【算法】计数排序以及其java实现
2017-12-19 20:04
316 查看
前几周算法课看算法导论看到一个排序叫计数排序,据说是一个很骚的东西,其时间复杂度为O(n)。要知道很骚的快速排序其平均时间复杂度也是O(nlgn)。看完了算法的推导过程才发现,原来只是一个空间换时间的策略。
首先,它需要我们准备三个数组,需要排序的数组A,排序后的数组B,二者同样大小。然后中间数组C,C的大小为A中最大值+1.(这个就很坑,比如我A[2] = {1,9999}那么它就会默认建立的C数组长度为10000。然而用别的排序根本用不到这么大的空间。没办法,谁让其的策略就是空间换时间呢) 然后C数组的下标代表A数组中的值,C数组对应下标的值代表下标值在A数组中出现的次数。如下图所示例子:
(别看这里的C长度为4,万一A中有0呢?)
然后对C中的每个值变化为其之前所有值与本身值之和,表示A中小于等于自己的一共有多少个数。
然后,从末尾遍历A数组,找寻A数组对应的值作为下标在C数组中对应的值。然后该值就是A数组中值在B数组中值的位置:
B数组更新完后,C数组对应的位置值-1.代表剩下的A数组中小于等于该值的个数。
依次遍历一遍,就将A数组中所有的值放到了B数组中对应的位置中。
总的说来,虽然其看起来时间复杂度是O(n),但是其背后的代价是蛮大的。所以只在巨大样本的排序中会比其他排序快。并且尽量控制A数组中最大值和A数组长度的比例,不然弄一个巨长的数组C但是其变化寥寥,就比较浪费空间了。
下面是java实现的源代码。由于经常刷leetcode,得了一种不把多余的全部删掉就会死的病。所以没有注释,代码也比较紧凑,见谅。
首先,它需要我们准备三个数组,需要排序的数组A,排序后的数组B,二者同样大小。然后中间数组C,C的大小为A中最大值+1.(这个就很坑,比如我A[2] = {1,9999}那么它就会默认建立的C数组长度为10000。然而用别的排序根本用不到这么大的空间。没办法,谁让其的策略就是空间换时间呢) 然后C数组的下标代表A数组中的值,C数组对应下标的值代表下标值在A数组中出现的次数。如下图所示例子:
(别看这里的C长度为4,万一A中有0呢?)
然后对C中的每个值变化为其之前所有值与本身值之和,表示A中小于等于自己的一共有多少个数。
然后,从末尾遍历A数组,找寻A数组对应的值作为下标在C数组中对应的值。然后该值就是A数组中值在B数组中值的位置:
B数组更新完后,C数组对应的位置值-1.代表剩下的A数组中小于等于该值的个数。
依次遍历一遍,就将A数组中所有的值放到了B数组中对应的位置中。
总的说来,虽然其看起来时间复杂度是O(n),但是其背后的代价是蛮大的。所以只在巨大样本的排序中会比其他排序快。并且尽量控制A数组中最大值和A数组长度的比例,不然弄一个巨长的数组C但是其变化寥寥,就比较浪费空间了。
下面是java实现的源代码。由于经常刷leetcode,得了一种不把多余的全部删掉就会死的病。所以没有注释,代码也比较紧凑,见谅。
public int[] JishuSort(int a[]) { int cnum =0; for(int i = 0 ; i<a.length;i++){ if(cnum<a[i]) cnum = a[i]; } int[] c = new int[cnum+1]; int[] b = new int[a.length]; for(int i =0;i<c.length;i++) c[i]=0; for(int i = 0;i<a.length;i++) c[a[i]]+=1; for(int i =1;i<c.length;i++) c[i]+=c[i-1]; for(int i = a.length-1;i>=0;i--){ b[c[a[i]]-1]=a[i]; c[a[i]]-=1; } return b; }
相关文章推荐
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案
- Java堆栈的应用1----------堆栈的自定义实现以及括号匹配算法的Java实现
- hihocoder#1055 : 刷油漆 算法详解以及java源码实现
- 0001算法--------全排列算法分析以及JAVA代码完美实现
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现
- java各种算法排序图解以及原码实现
- 机器学习算法——KNN分类算法介绍以及Java实现
- 机器学习算法——PCA算法介绍以及Java实现
- 算法-java代码实现计数排序
- 桶排序(计数排序)原理以及java实现
- Java文件Hash类,实现对计算进度的监视以及多算法的同时计算
- Java排序算法以及算法改进总结(计数排序、基数排序、桶排序)
- 算法--组合数学:杨辉三角数学分析以及Java实现
- 计数排序的思想,时间空间复杂度细致分析以及java源代码实现
- Java实现二叉树,以及先序、中序、后序遍历算法的实现
- 现代应用密码学中椭圆曲线求点集E以及点乘算法的java代码实现
- Twitter的分布式自增ID算法snowflake的JAVA实现以及使用时需要注意的问题
- 排序及选择算法的java实现(三)计数排序、计数选择、随机选择、最差线性时间选择
- 数据挖掘十大经典算法之Apriori算法以及Java实现