计数排序,属于桶排序特殊的一种。

当要排序n个数据的时候,如果所处的范围不大,我们可以取其中的最大值K,并将数据分散在K个桶里面,

每个桶里面的数据都是相同的(这样省去了桶内排序的时间),然后顺序取出就好啦。

当然计数排序说起来简单,写起来有些地方不好理解。

比如我们现在有2,5,3,0,2,3,0,3这8个数,要对它排序,我们就可以先取到它的最大值5,然后确定范围在0-5,

我们申请一个0-5的内存空间去分别计算每个位置对应的每个数的个数。

下图表示的就是0-5这个内存空间的数据,我们可以看到其中0出现了两次,1出现了0次,2出现了两次,3出现了三次,4出现了0次,5出现了一次。

同时还可以总结一些规律出来,比如我们现在看到c[2]这个位置,2出现了两次,在2前面c[0] + c[1]总共有2个元素,所以c[2]对应这两个2在原数组中

的位置是2,3,我们可以得出规律c[2]所在位置 = c[0] + c[1],后面的c[3]的位置 = c[2] + c[1],我们就这样挨着顺序求和:

然后我们扫描原数组2,5,3,0,2,3,0,3,每遇到一个数,就将该数代入c数组的索引中取出当前元素在排序之后真正的索引。

我的Java实现如下:

 package com.structure.sort;

 /**
* @author zhangxingrui
* @create 2019-01-30 13:45
**/
public class CountingSort { public static void main(String[] args) {
int[] numbers = {3, 9, 2, 1, 8, 7, 6, 10, 9};
// 假设数组中存储的都是非负整数
countingSort(numbers);
for (int number : numbers) {
System.out.println(number);
}
} /**
* @Author: xingrui
* @Description: 计数排序
* @Date: 13:57 2019/1/30
*/
private static void countingSort(int[] numbers){
int n = numbers.length;
int maxNumber = numbers[0];
for(int i = 1; i < n; ++i){
if(numbers[i] > maxNumber)
maxNumber = numbers[i];
} int[] r = new int[n];
int[] c = new int[maxNumber + 1]; for(int i = 0; i < n; ++i){
c[numbers[i]]++;
} for(int i = 1; i <= maxNumber; ++i){
c[i] = c[i-1] + c[i];
} for (int i = n - 1; i >= 0; --i){
int index = c[numbers[i]];
r[index - 1] = numbers[i];
c[index]--;
} for(int i = 0; i < n; ++i){
numbers[i] = r[i];
}
} }

其中关键的代码:

 for (int i = n - 1; i >= 0; --i){
int index = c[numbers[i]];
r[index - 1] = numbers[i];
c[index]--;
}

从c数组中取出排序之后的索引。

需要特别说明的是,文中的图片均截图极客网王争老师的专栏《数据结构与算法之美》,如有侵权,请联系我删除。

有需要的朋友也可以去订阅这个专栏,讲的挺不错的,没有视频,只有文字和音频。

小白初识 - 计数排序(CountingSort)的更多相关文章

  1. 计数排序(counting-sort)——算法导论(9)

    1. 比较排序算法的下界 (1) 比较排序     到目前为止,我们已经介绍了几种能在O(nlgn)时间内排序n个数的算法:归并排序和堆排序达到了最坏情况下的上界:快速排序在平均情况下达到该上界.   ...

  2. 计数排序(counting-sort)

    计数排序是一种稳定的排序算法,它不是比较排序.计数排序是有条件限制的:排序的数必须是n个0到k的数,所以计数排序不适合给字母排序.计数排序时间复杂度:O(n+k),空间复杂度:O(k),当k=n时,时 ...

  3. CountingSort(计数排序)原理及C++代码实现

    计数排序是需要假设输入数据的排序之一,它假设输入元素是0到k区间内的一个整数,其中k为某个整数.当k=O(n)时,计数排序的时间复杂度为θ(n). 因为不是通过比较来排序,所以它的时间复杂度可以达到θ ...

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

    算法说明 计数排序属于线性排序,它的时间复杂度远远大于常用的比较排序.(计数是O(n),而比较排序不会超过O(nlog2nJ)). 其实计数排序大部分很好理解的,唯一理解起来很蛋疼的是为了保证算法稳定 ...

  5. Python线性时间排序——桶排序、基数排序与计数排序

    1. 桶排序 1.1 范围为1-M的桶排序 如果有一个数组A,包含N个整数,值从1到M,我们可以得到一种非常快速的排序,桶排序(bucket sort).留置一个数组S,里面含有M个桶,初始化为0.然 ...

  6. 算法-java代码实现计数排序

    计数排序   第10节 计数排序练习题 对于一个int数组,请编写一个计数排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3], ...

  7. 《算法导论》——计数排序Counting Sort

    今天贴出的算法是计数排序Counting Sort.在经过一番挣扎之前,我很纠结,今天这个算法在一些scenarios,并不是最优的算法.最坏情况和最好情况下,时间复杂度差距很大. 代码Countin ...

  8. python实现线性排序算法-计数排序

    计数排序假定输入元素的每一个都是介于0到k之间的整数,此处K为某个整数,当k=O(n)时,计数排序的运行时间为O(n) 它的基本思想是:根据每个输入元素x确定小于x的元素个数,根据这个信息把x直接放到 ...

  9. 排序基础之非比较的计数排序、桶排序、基数排序(Java实现)

    转载请注明原文地址: http://www.cnblogs.com/ygj0930/p/6639353.html  比较和非比较排序 快速排序.归并排序.堆排序.冒泡排序等比较排序,每个数都必须和其他 ...

随机推荐

  1. use tool wget for windows download

    1.什么是wget Wget是一个在网络上进行下载的简单而强大的自由软件,其本身也是GNU计划的一部分.它的名字是"World Wide Web"和"Get"的 ...

  2. echo图片延迟加载js

    插件描述:和 Lazy Load 一样,Echo.js 也是一个用于图像延迟加载 JavaScript.不同的是 Lazy Load 是基于 jQuery 的插件,而 Echo.js 不依赖于 jQu ...

  3. [Luogu2622]关灯问题$||$(状压$DP$)

    #\(\color{red}{\mathcal{Description}}\) \(Link\) 现有\(n\)盏灯,以及\(m\)个按钮.每个按钮可以同时控制这\(n\)盏灯--按下了第i个按钮,对 ...

  4. SharePoint2010代码启动工作流

    1. private void StartWorkFlow() { //获得该列表上的发布的所有工作流 SPWorkflowAssociationCollection wfAssociationCol ...

  5. Centos 7安装Grafana 4及结合Zabbix3.2实现可视化监控图形

    上一篇介绍了如何在Centos 7环境下安装zabbix监控,本章继续介绍在Centos 7环境下安装Grafana,并结合Zabbix实现可视化监控图形! 简介: Grafana 是 Graphit ...

  6. Spring Boot Admin 2.1.0 全攻略

    转载请标明出处: https://www.fangzhipeng.com 本文出自方志朋的博客 Spring Boot Admin简介 Spring Boot Admin是一个开源社区项目,用于管理和 ...

  7. java通过IO流复制文件

    package kimoji; import java.io.*; public class FileTest { public static void main(String[] args) thr ...

  8. JAVA WEB 前台实时监控后台程序运行

    基本思路: 1. 操作状态在类中以静态变量方式(或公共类存储公共变量方式,SESSION方式.COOKIE方式)存在 2. 前台采用AJAX方式激发后台进行业务逻辑操作,并实时更新操作状态信息 3.  ...

  9. shell习题第3题:统计内存大小

    [题目要求] 写一个脚本计算一下linux系统所有进程占用内存的大小的和 [核心要点] ps命令用法 for循环 加法运算 [脚本] #!/bin/bash for n in `ps aux | gr ...

  10. ssm多数据源的操作

    公司要求,需要使用两个数据库,一个mysql,一个oracle.所以需要配置两个数据库来进行操作. 1.首先,需要在jdbc.properties文件中将两个库的配置数据写入,不过一个写driver, ...