前面介绍的几种排序算法,都是基于不同位置的元素比较,算法平均时间复杂度理论最好值是θ(nlgn).

今天介绍一种新的排序算法,计数排序(Counting sort),计数排序是一个非基于比较的线性时间排序算法。它对输入的数据有附加的限制条件:输入序列中数据取值范围有限,比如都是小于upperLimit的整数;

算法分3步实现:

1)遍历输入序列,统计不同取值的个数,放入计数数组;

2)遍历计数数组,计算不大于各个取值的个数,更新计数数组;

3)逆序遍历输入序列,结合计数数组中个数,将数据放到输出数组中。

(一)算法实现

 protected void sort(int[] toSort) {
int[] result = new int[toSort.length];
int[] countingArray = new int[upperLimit];
for (int i = ; i < toSort.length; i++) {
countingArray[toSort[i]]++;
}
for (int i = ; i < countingArray.length; i++) {
countingArray[i] += countingArray[i - ];
} for (int i = toSort.length - ; i >= ; i--) {
result[countingArray[toSort[i]] - ] = toSort[i];
countingArray[toSort[i]]--;
} System.arraycopy(result, , toSort, , result.length);
}

Counting Sort

1)算法时间复杂是θ(n+k),n表示输入序列中元素个数,k表示输入序列中元素取值集合的个数;

2)算法属于稳定排序;

3)算法不属于原地排序,需要额外空间存放计数数组和输出数组,空间复杂度是θ(n+k);

4)算法不是比较排序算法。

(二)仿真结果

下面是计数排序和随机化排序的比较,从结果看,当k=O(n)时,计数排序时间复杂度更低。

**************************************************
Number to Sort is:2500
Array to sort is:{735805,621178,561545,362760,60951,337406,317120,378387,25311,115277...}
Cost time of 【CountingSort】 is(milliseconds):4
Sort result of 【CountingSort】:{177,418,611,924,1139,1752,2048,2221,2918,3340...}
Cost time of 【RandomizedQuickSort】 is(milliseconds):0
Sort result of 【RandomizedQuickSort】:{177,418,611,924,1139,1752,2048,2221,2918,3340...}
**************************************************
Number to Sort is:25000
Array to sort is:{435929,221392,407142,872904,594585,726112,958590,976368,570033,848066...}
Cost time of 【CountingSort】 is(milliseconds):5
Sort result of 【CountingSort】:{24,42,79,134,142,257,268,462,503,544...}
Cost time of 【RandomizedQuickSort】 is(milliseconds):2
Sort result of 【RandomizedQuickSort】:{24,42,79,134,142,257,268,462,503,544...}
**************************************************
Number to Sort is:250000
Array to sort is:{426400,121941,600931,85753,455109,650154,341754,478839,921893,648842...}
Cost time of 【CountingSort】 is(milliseconds):16
Sort result of 【CountingSort】:{0,2,6,23,33,34,35,38,41,46...}
Cost time of 【RandomizedQuickSort】 is(milliseconds):28
Sort result of 【RandomizedQuickSort】:{0,2,6,23,33,34,35,38,41,46...}
**************************************************
Number to Sort is:2500000
Array to sort is:{26177,919623,668931,41665,236093,656020,473433,258087,659468,419426...}
Cost time of 【CountingSort】 is(milliseconds):206
Sort result of 【CountingSort】:{0,0,0,2,3,3,4,4,5,5...}
Cost time of 【RandomizedQuickSort】 is(milliseconds):334
Sort result of 【RandomizedQuickSort】:{0,0,0,2,3,3,4,4,5,5...}

相关代码:

 package com.cnblogs.riyueshiwang.sort;

 import java.util.Arrays;

 public class CountingSort extends abstractSort {

     private int upperLimit;

     public CountingSort(int upperLimit) {
this.upperLimit = upperLimit;
} @Override
protected void sort(int[] toSort) {
int[] result = new int[toSort.length];
int[] countingArray = new int[upperLimit];
for (int i = 0; i < toSort.length; i++) {
countingArray[toSort[i]]++;
}
for (int i = 1; i < countingArray.length; i++) {
countingArray[i] += countingArray[i - 1];
} for (int i = toSort.length - 1; i >= 0; i--) {
result[countingArray[toSort[i]] - 1] = toSort[i];
countingArray[toSort[i]]--;
} System.arraycopy(result, 0, toSort, 0, result.length);
} public static void main(String[] args) {
for (int j = 0, n = 2500; j < 4; j++, n = n * 10) {
System.out
.println("**************************************************");
System.out.println("Number to Sort is:" + n);
int upperLimit = 1000000;
int[] array = CommonUtils.getRandomIntArray(n, upperLimit);
System.out.print("Array to sort is:");
CommonUtils.printIntArray(array); int[] array1 = Arrays.copyOf(array, n);
new CountingSort(upperLimit).sortAndprint(array1); int[] array2 = Arrays.copyOf(array, n);
new RandomizedQuickSort().sortAndprint(array2);
}
}
}

CountingSort.java

排序算法六:计数排序(Counting sort)的更多相关文章

  1. 惊!世界上竟然有O(N)时间复杂度的排序算法!计数排序!

    啥?你以为排序算法的时间复杂度最快也只能O(N*log(N))了? O(N)时间复杂度的排序算法听说过没有?计数排序!!它是世界上最快最简单的算法!!! 计数排序算法操作起来只有三步,看完秒懂! 根据 ...

  2. 【DS】排序算法之希尔排序(Shell Sort)

    一.算法思想 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.希尔排序是非稳定排序算法.希尔排序是基于插入排序的以下两点性质而提出改进方法的:1)插入排序在对几乎已经排好序的数据操作 ...

  3. Java常见排序算法之Shell排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  4. Java实现基于桶式排序思想和计数排序思想实现的基数排序

    计数排序 前提:待排序表中的所有待排序关键字必须互不相同: 思想:计数排序算法针对表中的每个记录,扫描待排序的表一趟,统计表中有多少个记录的关键码比该记录的关键码小,假设针对某一个记录,统计出的计数值 ...

  5. Python排序算法之选择排序定义与用法示例

    Python排序算法之选择排序定义与用法示例 这篇文章主要介绍了Python排序算法之选择排序定义与用法,简单描述了选择排序的功能.原理,并结合实例形式分析了Python定义与使用选择排序的相关操作技 ...

  6. 排序算法总结------选择排序 ---javascript描述

    每当面试时避不可少谈论的话题是排序算法,上次面试时被问到写排序算法,然后脑袋一懵不会写,狠狠的被面试官鄙视了一番,问我是不是第一次参加面试,怎么可以连排序算法都不会呢?不过当时确实是第一次去面试,以此 ...

  7. 数据结构与算法之PHP排序算法(希尔排序)

    一.基本思想 希尔排序算法是希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接 ...

  8. 八大排序算法~简单选择排序【记录下标k变量的作用】

    八大排序算法~简单选择排序[记录下标k变量的作用] 1,思想:打擂台法,数组中的前n-1个元素依次上擂台"装嫩",后边的元素一个挨着一个不服,一个一个上去换掉它 2,优化:通过记录 ...

  9. 【算法】计数排序(Counting Sort)(八)

    计数排序(Counting Sort) 计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中. 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范 ...

随机推荐

  1. 搭建jumperserver堡垒机管理万台服务器-1

    搭建jumperserver堡垒机管理万台服务器-1 1  Jumpserver堡垒机概述-部署Jumpserver运行环境 2  安装Coco组件 3  安装Web-Terminal前端-Luna组 ...

  2. ST7735和ST7789驱动

    /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __LCD_H #de ...

  3. 二进制sersync部署安装

    一.为什么要用rsync+sersync架构? 1.sersync是基于inotify开发的,类似于inotify-tools的工具 2.sersync可以记录下被监听目录中发生变化的(包括增加.删除 ...

  4. window.open()的实际应用

    Window open() 方法 定义和用法 open() 方法用于打开一个新的浏览器窗口或查找一个已命名的窗口. 语法 window.open(URL,name,specs,replace) 参数 ...

  5. 错误消息对话框QErrorMessage

    继承于   QDialog 样式:   这个复选框的作用:文本框中相同信息时是否再显示 import sys from PyQt5.QtWidgets import QApplication, QWi ...

  6. 【宝藏】题解(五校联考3day1)

    分析 如果打爆搜的话可以拿60分. 首先知道期望是可以累加的,即i通过j去到k的期望,等于i去到j的期望加j去到k的期望. 所以令d[i]表示i的出度,F[i]表示从i到i的父亲的期望,G[i]表示i ...

  7. 【leetcode】All Paths From Source to Target

    题目如下: Given a directed, acyclic graph of N nodes. Find all possible paths from node 0 to node N-1, a ...

  8. A1065

    判断两数相加是否大于第三数,大于输出true,否则输出false(相等也是false) 1 需要注意数字溢出的问题: 2 先判断溢出,因为在a,b都是负数最小值的情况下,相加直接是正数,在c较小的时候 ...

  9. CMD命令行二

    图形化用户界面 calc control mmc notepad regedit (start命令也有用) dir | findstr /i "for" 忽略大小写查找 finds ...

  10. Linux6.6及以上版本配置oracle-ASM共享储存-UDEV

    在linux6.6版本之前,我们又两种方式可以配置asm共享磁盘,一种是安装asm驱动包进行asm磁盘组配置,另一种是UDEV通过识别共享存储UUID号进行asm磁盘组配置. 但在linux6.6之后 ...