排序9-计数排序

超、凢脫俗 2022-12-23 14:24 158阅读 0赞
  1. 计数排序是一种非基于比较的排序算法,我们之前介绍的各种排序算法几乎都是基于元素之间的比较来进行排序的,计数排序的时间复杂度为O(n+m),m指的是数据量,说的简单点,计数排序算法的时间复杂度约等于O(n),快于任何比较型的排序算法.
  2. 其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

1. 算法描述:

  • 找出待排序的数组中最大和最小的元素;
  • 统计数组中每个值为i的元素出现的次数,存入数组C的第i项;
  • 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);
  • 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。

2. 动图演示.

20201125150548956.gif

  1. \[3,5,8,2,5,4\]这组数字来演示。
  2. 首先,我们找到这组数字中最大的数,也就是8,创建一个最大下标为8的空数组arr

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYW5neWluZ2NoZW5ncWk_size_16_color_FFFFFF_t_70

遍历数据,将数据的出现次数填入arr中对应的下标位置中。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYW5neWluZ2NoZW5ncWk_size_16_color_FFFFFF_t_70 1

遍历arr,将数据依次取出即可。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYW5neWluZ2NoZW5ncWk_size_16_color_FFFFFF_t_70 2

  1. 代码实现:

    public static void sort(int[] arr) {

    1. //找出数组中的最大值
    2. int max = arr[0];
    3. for (int i = 1; i < arr.length; i++) {
    4. if (arr[i] > max) {
    5. max = arr[i];
    6. }
    7. }
    8. //初始化计数数组
    9. int[] countArr = new int[max + 1];
    10. //计数
    11. for (int i = 0; i < arr.length; i++) {
    12. countArr[arr[i]]++;
    13. arr[i] = 0;
    14. }
    15. //排序
    16. int index = 0;
    17. for (int i = 0; i < countArr.length; i++) {
    18. if (countArr[i] > 0) {
    19. arr[index++] = i;
    20. }
    21. }
    22. }
  2. 分析:

    计数排序是一个稳定的排序算法。当输入的元素是 n 个 0到 k 之间的整数时,时间复杂度是O(n+k),空间复杂度也是O(n+k),其排序速度快于任何比较排序算法。当k不是很大并且序列比较集中时,计数排序是一个很有效的排序算法。

  3. 应用案例:

    需求描述: 对学生的成绩进行排序输出。 (注意: 计数排序是稳定的排序,原来排前面的人,排序后还是处于相同成绩的人的前面)

    //定义学生类
    public class Student {

    1. public String sname;
    2. public int score;
    3. public Student(String sname, int score) {
    4. this.sname = sname;
    5. this.score = score;
    6. }
    7. @Override
    8. public String toString() {
    9. return "Student{" +
    10. "sname='" + sname + '\'' +
    11. ", score=" + score +
    12. "}";
    13. }

    }

    public class Main {

    1. public static void main(String[] args) {
    2. Random r=new Random();
    3. Student[] ss=new Student[10];
    4. for( int i=0;i<ss.length;i++){
    5. ss[i]=new Student( "张"+i, r.nextInt( 50)+50 );
    6. }
    7. System.out.println("原数组:");
    8. for( Student s: ss){
    9. System.out.println( s );
    10. }
    11. System.out.println("排序后");
    12. sort( ss );
    13. for( int i=ss.length-1;i>=0;i--){
    14. System.out.println( ss[i] );
    15. }
  1. }
  2. public static void sort(Student[] arr) {
  3. //找出数组中的最大值
  4. Student max = arr[0];
  5. for (int i = 1; i < arr.length; i++) {
  6. if (arr[i].score > max.score) {
  7. max = arr[i];
  8. }
  9. }
  10. //初始化计数数组
  11. int[] countArr = new int[max.score + 1];
  12. //计数
  13. for (int i = 0; i < arr.length; ++i) {
  14. countArr[arr[i].score]++;
  15. }
  16. //顺序累加
  17. for (int i = 1; i < max.score + 1; ++i) {
  18. countArr[i] = countArr[i-1] + countArr[i];
  19. }
  20. //排序后的数组
  21. Student[] sortedArr = new Student[arr.length];
  22. //排序
  23. for (int i = arr.length - 1; i >= 0; --i) {
  24. sortedArr[countArr[arr[i].score]-1] = arr[i];
  25. countArr[arr[i].score]--;
  26. }
  27. //将排序后的数据拷贝到原数组
  28. for (int i = 0; i < arr.length; ++i) {
  29. arr[i] = sortedArr[i];
  30. }
  31. }
  32. }

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYW5neWluZ2NoZW5ncWk_size_16_color_FFFFFF_t_70 3

发表评论

表情:
评论列表 (有 0 条评论,158人围观)

还没有评论,来说两句吧...

相关阅读

    相关 排序算法 - 计数排序

    基本思想 计数排序是一种线性排序算法,它利用了一个数组,因为数组下标的增长是线性的,所以它就把自己的元素转换成新开辟数组的下标。可是下标都是非负数啊?数组当中的值有正有负

    相关 排序9-计数排序

           计数排序是一种非基于比较的排序算法,我们之前介绍的各种排序算法几乎都是基于元素之间的比较来进行排序的,计数排序的时间复杂度为O(n+m),m指的是数据量,说的简单

    相关 排序算法——计数排序

    排序算法——计数排序 > 计数排序是一个非基于比较的排序算法。它的优势在于在对一定范围内的整数排序时,快于任何比较排序算法。 这是一种牺牲空间换取时间的做法,当O(k)>

    相关 排序算法 —— 计数排序

    引言 计数排序是桶排序思想的一种具体实现,针对一些具有特殊限制的样本数据,如公司员工年龄,那么样本数据本身就一定在0~200之间,针对这样的数据,使用从0到200 的桶数

    相关 排序算法——计数排序

    前言 计数排序的思想:在给定的数组中,依次寻找比当前数字小的元素的个数(count),统计之后直接使用t就可以定位到该数所在的位置,因为比它小的元素的个数已经通过coun

    相关 计数排序

    计数排序: 假设n个输入元素中的每一个都是在0~区间内的一个整数,其中k为某个整数。当k=O(n)是,排序时间为O(n). 基本思想:对每个输入元素x,确定小于x元素的