算法说明

计数排序属于线性排序,它的时间复杂度远远大于常用的比较排序。(计数是O(n),而比较排序不会超过O(nlog2nJ))。

其实计数排序大部分很好理解的,唯一理解起来很蛋疼的是为了保证算法稳定性而做的数据累加,大家听我说说就知道了:

1、首先,先取出要排序数组的最大值,假如我们的数组是int[] arrayData = { 2, 4, 1, 5, 6, 7, 4, 65, 42 };,那么最大值就是65.(代码17-21行就是在查找最大值)

2、然后创建一个计数数组,计数数组的长度就是我们的待排序数组长度+1。即65+1=66。计数数组的作用就是用来存储待排序数组中,数字出现的频次。 例如,4出现了两次,那么计数数组arrayCount[4]=2。 OK,现在应该明白为什么计数数组长度为什么是66而不是65了吧? 因为为了存储0

然后再创建一个存储返回结果的数组,数组长度与我们的原始数据长度是相同的。(24和26行)

3、进行计数(代码29至31行)

4、将计数数组进行数量累计,即arrayCount[i]+=arrayCount[i-1](代码35行至代码37行)。 

   目的是为了数据的稳定性, 这块我其实看了许久才看懂的…再次证明我的资质真的很差劲。 我来尽力解释一下:

其实这个与后边那步结合着看理解起来应该更容易些。

例如我们计数数组分别是 1 2 1 2 1 的话,那么就代表0出现了一次,1出现了两次,2出现了一次,3出现了两次。

  这个是很容易理解的。 那我们再换个角度来看这个问题。

  我们可以根据这个计数数组得到每个数字出现的索引位置,即数字0出现的位置是索引0,数字1出现的问题是索引1,2;数字2出现的位置是索引3,数字4出现的位置是索引4,5。。。。

  OK,大家可以看到,这个索引位置是累加的,所以我们需要arrayCount[i]+=arrayCount[i-1]来存储每个数字的索引最大值。 这样为了后边的输出

5、最后,把原始数据从后往前输出;然后每个数字都能找到计数器的最后实现索引。  然后将数字存储在实际索引的结果数组中。 然后计数数组的索引--, 结果就出来了。

PS:计数排序其实是特别吃内存的,所以应用场景是最大值确定并且不大,必须是正整数。

时间复杂度:

O(n+k)

请对照下方代码:因为有n的循环,也有k的循环,所以时间复杂度是n+k

空间复杂度:

O(n+k)

请对照下方代码:需要一个k+1长度的计数数组,需要一个n长度的结果数组,所以空间复杂度是n+k

代码

使用的是java

/*
* 计数排序
*/
public class CountingSort {
public static void main(String[] args) {
int[] arrayData = { 2, 3, 1, 5, 6, 7, 4, 65, 42 };
int[] arrayResult = CountintSort(arrayData);
for (int integer : arrayResult) {
System.out.print(integer);
System.out.print(" ");
}
} public static int[] CountintSort(int[] arrayData) {
int maxNum = 0;
// 取出最大值
for (int i : arrayData) {
if (i > maxNum) {
maxNum = i;
}
} // 计数数组
int[] arrayCount = new int[maxNum + 1];
// 结构数组
int[] arrayResult = new int[arrayData.length]; // 开始计数
for (int i : arrayData) {
arrayCount[i]++;
} // 对于计数数组进行 i=i+(i-1)
// 目的是为了保证数据的稳定性
for (int i = 1; i < arrayCount.length; i++) {
arrayCount[i] = arrayCount[i] + arrayCount[i - 1];
} for (int i = arrayData.length - 1; i >= 0; i--) {
arrayResult[arrayCount[arrayData[i]] - 1] = arrayData[i];
arrayCount[arrayData[i]]--;
} return arrayResult; }
}

结果

1 2 3 4 5 6 7 42 65

参考:

http://blog.csdn.net/sjin_1314/article/details/8655061

http://www.cnblogs.com/eaglet/archive/2010/09/16/1828016.html

Hark的数据结构与算法练习之计数排序的更多相关文章

  1. Hark的数据结构与算法练习之锦标赛排序

    算法说明 锦标赛排序是选择排序的一种. 实际上堆排序是锦标赛排序的优化版本,它们时间复杂度都是O(nlog2n),不同之处是堆排序的空间复杂度(O(1))远远低于锦标赛的空间复杂度(O(2n-1)) ...

  2. Hark的数据结构与算法练习之圈排序

    算法说明 圈排序是选择排序的一种.其实感觉和快排有一点点像,但根本不同之处就是丫的移动的是当前数字,而不像快排一样移动的是其它数字.根据比较移动到不需要移动时,就代表一圈结束.最终要进行n-1圈的比较 ...

  3. Hark的数据结构与算法练习之Bogo排序

    算法说明 Bogo排序是交换排序的一种,它是一种随机排序,也是一种没有使用意义的排序,同样也是一种我觉得很好玩的排序. 举个形象的例子,你手头有一副乱序的扑克牌,然后往天上不停的扔,那么有一定机率会变 ...

  4. Hark的数据结构与算法练习之珠排序

    ---恢复内容开始--- 算法说明 珠排序是分布排序的一种. 说实在的,这个排序看起来特别的巧妙,同时也特别好理解,不过不太容易写成代码,哈哈. 这里其实分析的特别好了,我就不画蛇添足啦.  大家看一 ...

  5. Hark的数据结构与算法练习之梳排序

    算法说明梳排序是交换排序的一种,它其实也是改自冒泡排序,不同之处是冒泡排序的比较步长恒定为1,而梳排序的比较步长是变化的. 步长需要循环以数组长度除以1.3,到最后大于等于1即可. 光说可能比较抽象, ...

  6. Hark的数据结构与算法练习之奇偶排序

    算法说明 奇偶排序又叫奇偶换位排序,砖排序.它是一种交换排序,也是冒泡的一个变种 顾名思义,奇偶排序,其实就是先循环奇数位,然后将奇数位与偶数位比较计算. 然后再循环偶数位,再和奇数位比较运算.看一下 ...

  7. Hark的数据结构与算法练习之鸡尾酒排序

    算法说明 鸡尾酒排序又叫定向冒泡排序,鸡尾酒搅拌排序,搅拌排序,涟漪排序,回来排序,快乐小时排序. 鸡尾酒排序是交换排序的一种,它是冒泡排序的一个轻微的变种.冒泡是从低向高比较排序,鸡尾酒从低向高,从 ...

  8. Hark的数据结构与算法练习之煎饼排序

    算法说明 假设煎锅里边有N个煎饼摞在了一起,它们大小不一并且顺序不一致,我们需要通过拿铲子将它们不停的翻个,进行排序,最终得到一个底下是大的煎饼,上边是小的煎饼的序列.这个排序的过程就是煎饼排序. 这 ...

  9. Hark的数据结构与算法练习之图书馆排序

    算法说明 图书馆排序是插入排序的变种,典型的以空间换时间的一种方法.我个人感觉这种思路可以学习借鉴,但直接使用的场景应该不大. 我们知道,真正的插入排序通常往前边插入元素后,我们要把后边所有的元素后移 ...

随机推荐

  1. [Effective JavaScript 笔记]第43条:使用Object的直接实例构造轻量级的字典

    js对象的核心是一个字符串属性名与属性值的映射表.使用对象实现字典易如反掌,字典是可变长的字符串与值的映射集合. for...in js提供了枚举一个对象属性名的利器--for...in循环. var ...

  2. 如何让Ubuntu系统支持WebP图片格式

    本文主要向大家介绍如何让 Ubuntu 系统支持查看 WebP 图片格式,以及如何将 WebP 转为 JPEG 或 PNG 图片格式的方法. 什么是WebP图片 Google开发并推出 WebP 图片 ...

  3. lvs之ip-tun(ip隧道)技术的学习与实践

    1.配置测试环境 修改IP windows 200.168.10.4 lvs server  ip:200.168.10.1 因为IP隧道模式只需要一个网卡  所以就停掉其他网卡 web server ...

  4. linux 查看系统信息命令(比较全)

    linux 查看系统信息命令是linux初学者必备的基础知识, 这些命令也非常有用, 因为进入linux第一件事就可能是首先查看系统信息, 因此必要的系统的学习一下这些linux系统信息命令还是非常有 ...

  5. svn安装【转载】

    SVN简介        SVN全名Subversion,即版本控制系统.SVN与CVS一样,是一个跨平台的软件,支持大多数常见的操作系统.作为一个开源的版本控制系统,Subversion管理着随时间 ...

  6. Ubuntu14.04server开放rootssh登录权限

    刚安装了Ubuntu 14.04 server的虚拟机,普通帐号可以远程登录,但是root不行,输入密码后一直报错: permission denied 最后发现ssh的配置(/etc/ssh/ssh ...

  7. Linux: xclip,pbcopy,xsel用法 terminal 复制粘帖 (mac , ubuntu)

    ubuntu下的用户可以只用apt-get来安装: sudo apt-get install xclip echo "Hello, world" | xclip mac下使用pbc ...

  8. 【leetcode】Palindrome Partitioning II

    Palindrome Partitioning II Given a string s, partition s such that every substring of the partition ...

  9. eclipse debug source not fount

    1.选择Edit Source Lookup Path 2.选择Add 3.选择Java Project 4.选择相应的Project 进行OK确定即可 注意:做完以上的操作,要清除一下原来的断点,然 ...

  10. scrapy爬虫成长日记之将抓取内容写入mysql数据库

    前面小试了一下scrapy抓取博客园的博客(您可在此查看scrapy爬虫成长日记之创建工程-抽取数据-保存为json格式的数据),但是前面抓取的数据时保存为json格式的文本文件中的.这很显然不满足我 ...