排序算法 - 计数排序

概念:


计数排序不是一个比较排序算法,该算法于1954年由 Harold H. Seward提出,通过计数将时间复杂度降到了O(N),利用数组下标来缺的元素的正确位置


案例:


假设数组中有10个随机数,取值范围0~10,要求用最快的速度把这20个证书从小到大进行排序

考虑到这些整数只能够在 0、1、2、3、4、5、6、7、8、9、10 这11个数中取值,取值范围有限。所以,可以根据这有限的范围,建立一个长度为11的数组,数组下标从0-10,元素初始值全为0

在这里插入图片描述

假设10个随机数整数值如下

9,3,5,4,9,1,2,7,8,1

第一次计数

在这里插入图片描述

第二次计数

在这里插入图片描述

第三次计数

在这里插入图片描述

第四次计数

在这里插入图片描述

第五次计数

在这里插入图片描述

第六次计数

在这里插入图片描述

第七次计数

在这里插入图片描述

第八次计数

在这里插入图片描述

第九次计数

在这里插入图片描述

第十次计数

在这里插入图片描述

最终,当数列遍历完毕时,数组状态如下

在这里插入图片描述

该数组中每一个下标位置的值代表数列中对应整数出现的次数。

有了这个统计结果,排序就简单多了,直接便利数组,输出数组元素的下标值,元素的值时几,就输出几次

1,1,2,3,4,5,7,8,9,9

显然,现在输出的数列已经是有序的了。

这就是计数排序的基本过程,它适用于一定范围内的整数排序。在取值范围不是很大的情况下,它的性能甚至快过那些时间复杂度为 O(nlogn) 的排序。


代码实现:


public class test {

    public static void main(String[] args) {
        int[] array = new int[] {4,4,6,5,3,2,8,1,7,10};
        int[] sortedArray = countSort(array);
        System.out.println(Arrays.toString(sortedArray));
    }

    public static int[] countSort(int[] array){
        //1. 得到数列最大值
        int max = array[0];
        for (int i = 1; i < array.length; i++) {
            if(array[i] > max){
                max = array[i];
            }
        }
        //2. 根据数列最大值确定统计数组的长度
        int[] countArray = new int[max+1];
        for(int i=0; i<array.length; i++){
            countArray[array[i]]++;
        }
        //遍历统计数组,输出结果
        int index = 0;
        int[] sortedArray = new int[array.length];
        for(int i=0; i<countArray.length; i++){
            for(int j=0; j<countArray[i]; j++){
                sortedArray[index++] = i;
            }
        }
        return sortedArray;
    }

}

[1, 2, 3, 4, 4, 5, 6, 7, 8, 10]

这段代码在开头有一个步骤,就是求数列的最大整数值max。后面创建 的统计数组countArray,长度是max+1,以此来保证数组的最后一个下 标是max。


计数排序优缺点


  1. 当数列最大和最小值差距过大时,并不适合用计数排序

例如给出20个随机整数,范围在0到1亿之间,这时如果使用计数排序,需要创建长度为1亿的数组,不但浪费空间,而且时间复杂度也会随之升高

  1. 当数列元素不是整数时,也不适合用计数排序

如果数列中的元素都是小数,如25.213,或0.00 000 001 这样的数字,则无法创建对应统计数组,这样显然无法进行计数排序。

对于这些局限性,另一种线性时间排序算法做出弥补、这周排序算法叫做桶排序




个人博客地址:http://blog.yanxiaolong.cn | <font color = "orange"> 『纵有疾风起,人生不言弃』 </font>

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 初始计数排序 摘自漫画算法: 计数排序是一种不基于元素比较,利用数组索引来确定元素的正确位置的。 假设数组中有20...
    花逝97阅读 3,446评论 0 1
  • 题外话计数排序时间性能比之前的排序算法高,在实际中应用较多,只需要O(n)时间即可完成排序。计数排序思想比较巧妙,...
    哪有岁月静好阅读 2,507评论 0 0
  • 核心思想 计数排序不是基于比较的排序算法,算法的核心有3点:统计原数组中每个元素出现的次数。以原数组中的元素为下标...
    Alisallon阅读 4,804评论 0 1
  • 前面说的那些排序算法,都是要通过比较来实现的。排序还能不通过比较来实现?是的,计数排序就是这么神奇。 一、排序思想...
    贪挽懒月阅读 3,493评论 0 1
  • 计数排序 基本思想:不通过比较,计下每个元素的出现次数,统计小于这个元素的个数N,将其放在N位。例如{7,6,2,...
    守敬阅读 6,709评论 1 2

友情链接更多精彩内容