看动画学算法之:排序-count排序
简介
今天我们介绍一种不需要作比较就能排序的算法:count排序。
count排序是一种空间换时间的算法,我们借助一个外部的count数组来统计各个元素出现的次数,从而最终完成排序。
count排序的例子
count排序有一定的限制,因为外部的count数组长度是和原数组的元素范围是一致的,所以count排序一般只适合数组中元素范围比较小的情况。
我们举一个0-9的元素的排序的例子:3,4,2,5,6,2,4,9,1,3,5。
先看一个动画,看看是怎么排序的:

count数组里面存放的是从0到9这些元素出现的次数。
我们遍历原始数组,遇到相应的数字就给相应的count+1。
等所有的元素都count之后,再根据count数组中的值还原排序过后的数组。
count排序的java实现
count排序很简单,我们主要掌握下面两个大的步骤:
- 遍历原始数组,构建count数组。
- 根据count数组中的count值,重新构建排序数组。
public class CountingSort {
public void doCountingSort(int[] array){
int n = array.length;
// 存储排序过后的数组
int output[] = new int[n];
// count数组,用来存储统计各个元素出现的次数
int count[] = new int[10];
for (int i=0; i<10; ++i) {
count[i] = 0;
}
log.info("初始化count值:{}",count);
// 将原始数组中数据出现次数存入count数组
for (int i=0; i<n; ++i) {
++count[array[i]];
}
log.info("count之后count值:{}",count);
//遍历count,将相应的数据插入output
int j=0;
for(int i=0; i<10; i++){
while(count[i]-- > 0){
output[j++]=i;
}
}
log.info("构建output之后的output值:{}",output);
//将排序后的数组写回原数组
for (int i = 0; i<n; ++i)
array[i] = output[i];
}
public static void main(String[] args) {
int[] array= {3,4,2,5,6,2,4,9,1,3,5};
CountingSort countingSort=new CountingSort();
log.info("countingSort之前的数组为:{}",array);
countingSort.doCountingSort(array);
}
}
上面的注释应该很清楚了。
运行的结果如下:

count排序的第二种方法
在我们获得count数组中每个元素的个数之后,其实我们还有另外一个生成结果数组的办法:
// 这里是一个小技巧,我们根据count中元素出现的次数计算对应元素第一次应该出现在output中的下标。
//这里的下标是从右往左数的
for (int i=1; i<10; i++) {
count[i] += count[i - 1];
}
log.info("整理count对应的output下标:{}",count);
// 根据count中的下标,构建排序后的数组
//插入一个之后,相应的count下标要减一
for (int i = n-1; i>=0; i--)
{
output[count[array[i]]-1] = array[i];
--count[array[i]];
}
log.info("构建output之后的output值:{}",output);
主要分为两步:
第一步我们根据count中元素出现的次数计算对应元素第一次应该出现在output中的下标。这里的下标是从右往左数的。
第二步根据count中的下标,构建排序后的数组,插入一个之后,相应的count下标要减一。

可能不是很好理解,大家可以结合输出结果反复琢磨一下。
count排序的时间复杂度
从上面的代码我们可以看到,count排序实际上只做了少量次数的遍历。所以它的时间复杂度是O(n)。
本文的代码地址:
本文已收录于 http://www.flydean.com/algorithm-count-sort/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
看动画学算法之:排序-count排序的更多相关文章
- 看动画学算法之:二叉搜索树BST
目录 简介 BST的基本性质 BST的构建 BST的搜索 BST的插入 BST的删除 简介 树是类似于链表的数据结构,和链表的线性结构不同的是,树是具有层次结构的非线性的数据结构. 树是由很多个节点组 ...
- 看动画学算法之:linkedList
目录 简介 linkedList的构建 linkedList的操作 头部插入 尾部插入 中间插入 删除节点 简介 linkedList应该是一种非常非常简单的数据结构了.节点一个一个的连接起来,就成了 ...
- 看动画学算法之:栈stack
目录 简介 栈的构成 栈的实现 使用数组来实现栈 使用动态数组来实现栈 使用链表来实现 简介 栈应该是一种非常简单并且非常有用的数据结构了.栈的特点就是先进后出FILO或者后进先出LIFO. 实际上很 ...
- 看动画学算法之:平衡二叉搜索树AVL Tree
目录 简介 AVL的特性 AVL的构建 AVL的搜索 AVL的插入 AVL的删除 简介 平衡二叉搜索树是一种特殊的二叉搜索树.为什么会有平衡二叉搜索树呢? 考虑一下二叉搜索树的特殊情况,如果一个二叉搜 ...
- 看动画学算法之:队列queue
目录 简介 队列的实现 队列的数组实现 队列的动态数组实现 队列的链表实现 队列的时间复杂度 简介 队列Queue是一个非常常见的数据结构,所谓队列就是先进先出的序列结构. 想象一下我们日常的排队买票 ...
- 看动画学算法之:hashtable
目录 简介 散列表的关键概念 数组和散列表 数组的问题 hash的问题 线性探测 二次探测 双倍散列 分离链接 rehash 简介 java中和hash相关并且常用的有两个类hashTable和has ...
- 看动画学算法之:doublyLinkedList
目录 简介 doublyLinkedList的构建 doublyLinkedList的操作 头部插入 尾部插入 插入给定的位置 删除指定位置的节点 简介 今天我们来学习一下复杂一点的LinkedLis ...
- 看动画学算法之:双向队列dequeue
目录 简介 双向队列的实现 双向队列的数组实现 双向队列的动态数组实现 双向队列的链表实现 双向链表的时间复杂度 简介 dequeue指的是双向队列,可以分别从队列的头部插入和获取数据,也可以从队列的 ...
- JavaScript 数据结构与算法之美 - 桶排序、计数排序、基数排序
1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算 ...
随机推荐
- python setup.py install 报错【Project namexxx was given, but was not able to be found.】
错误信息: [root@wangjq networking-mirror]# python setup.py install /usr/lib64/python2./distutils/dist.py ...
- Python中print()函数不换行的方法以及分隔符替换
一.让print()函数不换行 在Python中,print()函数默认是换行的.但是,在很多情况下,我们需要不换行的输出(比如在算法竞赛中).那么,在Python中如何做到这一点呢? 其实很简单.只 ...
- Vue 构造选项 - 进阶
Directive指令:减少DOM操作的重复 Vue实例/组件用于数据绑定.事件监听.DOM更新 Vue指令主要目的就是原生DOM操作 减少重复 自定义指令 两种声明方式 方法一:声明一个全局指令 V ...
- RedHat 6.8 离线安装Docker (rpm包安装)
我的环境: [root@localhost ~]# uname -r 2.6.32-642.el6.x86_64 [root@localhost ~]# cat /etc/redhat-release ...
- 神舟zx6-ct5da装黑苹果Macos 10.15.6记录
可能是一时脑子抽风,突然就想体验一把mac系统.以前就了解过,给非苹果电脑装macos叫黑苹果,emmmmm.好吧,给我的神船也整一个. 看了很多个视频,整理一下装黑苹果过程.本人电脑系统是win10 ...
- 开始System.out.println();
第一篇博客 我在逛别人的博客的时候,发现他们有些内容是写他们自己的人生,有些是关于技术方面的个人观点分享探讨,每当看到好的文章的时候,我已经习惯的去点击收藏.有的时候我也在想,我为什么就不能做一个输出 ...
- SICP之应用序和正则序
以一个题目来说明 (define (square x) (* x x)) (define (sum-squares x y) (+ (square x) (square y))) (define (f ...
- JS - 对金额数字实现千分位格式化处理
添加千分位处理: function fmoney(s, n) { n = n > 0 && n < = 20 ? n : 2; s = parseFloat((s + &q ...
- PJSIP开发指南
一.通用设计 1.1 架构 1.1.1 通信图 下面的图展示了SIP消息在PJSIP组件间从后端到前端如何传递的. 1.1.2 类图 下面的图显示类视图 1.2 E ...
- oracle 11G R2卸载说明
oracle 11G R2数据库卸载