简介

今天我们介绍一种不需要作比较就能排序的算法: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排序很简单,我们主要掌握下面两个大的步骤:

  1. 遍历原始数组,构建count数组。
  2. 根据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)。

本文的代码地址:

learn-algorithm

本文已收录于 http://www.flydean.com/algorithm-count-sort/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

看动画学算法之:排序-count排序的更多相关文章

  1. 看动画学算法之:二叉搜索树BST

    目录 简介 BST的基本性质 BST的构建 BST的搜索 BST的插入 BST的删除 简介 树是类似于链表的数据结构,和链表的线性结构不同的是,树是具有层次结构的非线性的数据结构. 树是由很多个节点组 ...

  2. 看动画学算法之:linkedList

    目录 简介 linkedList的构建 linkedList的操作 头部插入 尾部插入 中间插入 删除节点 简介 linkedList应该是一种非常非常简单的数据结构了.节点一个一个的连接起来,就成了 ...

  3. 看动画学算法之:栈stack

    目录 简介 栈的构成 栈的实现 使用数组来实现栈 使用动态数组来实现栈 使用链表来实现 简介 栈应该是一种非常简单并且非常有用的数据结构了.栈的特点就是先进后出FILO或者后进先出LIFO. 实际上很 ...

  4. 看动画学算法之:平衡二叉搜索树AVL Tree

    目录 简介 AVL的特性 AVL的构建 AVL的搜索 AVL的插入 AVL的删除 简介 平衡二叉搜索树是一种特殊的二叉搜索树.为什么会有平衡二叉搜索树呢? 考虑一下二叉搜索树的特殊情况,如果一个二叉搜 ...

  5. 看动画学算法之:队列queue

    目录 简介 队列的实现 队列的数组实现 队列的动态数组实现 队列的链表实现 队列的时间复杂度 简介 队列Queue是一个非常常见的数据结构,所谓队列就是先进先出的序列结构. 想象一下我们日常的排队买票 ...

  6. 看动画学算法之:hashtable

    目录 简介 散列表的关键概念 数组和散列表 数组的问题 hash的问题 线性探测 二次探测 双倍散列 分离链接 rehash 简介 java中和hash相关并且常用的有两个类hashTable和has ...

  7. 看动画学算法之:doublyLinkedList

    目录 简介 doublyLinkedList的构建 doublyLinkedList的操作 头部插入 尾部插入 插入给定的位置 删除指定位置的节点 简介 今天我们来学习一下复杂一点的LinkedLis ...

  8. 看动画学算法之:双向队列dequeue

    目录 简介 双向队列的实现 双向队列的数组实现 双向队列的动态数组实现 双向队列的链表实现 双向链表的时间复杂度 简介 dequeue指的是双向队列,可以分别从队列的头部插入和获取数据,也可以从队列的 ...

  9. JavaScript 数据结构与算法之美 - 桶排序、计数排序、基数排序

    1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算 ...

随机推荐

  1. JavaFX桌面应用-loading界面

    上次使用JavaFX开发了一个视频转码工具,当用户点击"启动"按钮开始转码的时候,会禁用启动按钮,防止多次启动转码. 这种处理方式对用户来说可能并是很友好,其实可以在启动转码的时弹 ...

  2. AWS 学习笔记之 VPC

    原文:https://ericfu.me/aws-notes-vpc/ VPC 把 VPC 想象成一个逻辑上的数据中心 包含一个 IGW (Internet Gateway)或者 Virtual Pr ...

  3. Mysql安装错误

    [问题一]在安装mysql时遇到以下错误 执行./mysqld --initialize 后 ./bin/mysqld: error while loading shared libraries: l ...

  4. 对接接口时,组织参数json出现的问题

    在进行对接第三方接口时,进行参数组装成json的过程中出现参数传递格式错误以及json格式化错误. 在拼接json时,如果json中有对象,则以map的方式组装好所有参数.最后map转成json,不然 ...

  5. PostgreSQL在不同的表空间移动数据文件

    一.背景 在工作中,可能会遇到将表从一个表空间移动另一个表空间.例如 * 对数据进行冷处理 * 表空间所在的磁盘空间不足 * 建表时分配错了表空间 以上等等,可能需要你将一个表移动表空间. 二.表空间 ...

  6. cg语言学习&&阳春白雪GPU编程入门学习

    虽然所知甚少,但康大的<GPU编程与Cg编程之阳春白雪下里巴人>确实带我入了shader的门,在里面我第一次清晰地知道了“语义”的意思,非常感谢. 入门shader,我觉得可以先读3本书: ...

  7. C# .NET容器的源码

    这里有List<T>的源码http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs

  8. laravel5Eloquent模型与数据表的创建

    下面是有关管理员模型与表的创建 生成模型时同时生成数据库迁移文件 在生成的迁移文件中添加字段 运行命令行生成数据表 命令进行混合运用 生成工厂文件,数据填充文件 工厂模型代码 数据填充文件代码 数据填 ...

  9. UVA 11292-Dragon of Loowater (贪心)

    Once upon a time, in the Kingdom of Loowater, a minor nuisance turned into a major problem. The shor ...

  10. JVM内存区域与垃圾回收

    1.JAVA内存区域与内存溢出 1.1.概述 Java中JVM提供了内存管理机制,Java虚拟机在执行Java程序的过程中会把内分分为不同的数据区,如图: 1.2.程序计数器 程序计数器是当前线程所执 ...