五、排序算法总结三(计数排序)

计数排序

一、什么是计数排序

  当我们排序的时候,是对于一定范围的字符进行排序的。

  比如如果是a-z26个字母排序,这个时候可能出现的字母总数一共是26个,依次遍历字母出现的顺序,然后按照字母顺序以及出现的次数重新排列就可以了。

  如果是数字排序,也是这样,找到出现的数字的范围,然后对于范围以内的进行遍历,确定不同的数字出现的次数,然后按照次数一次排序。

二、例子

  例子一

  有这样的字母:  abdefde

  当我们遍历的时候得到如下的表格

字母 a b c d e f
遍历之后得到每个字母出现的次数 1 1 0 2 2 1

  随后按照每个字母的顺序,出现几次就排几个,排序之后出现的结果如图所示:

0 1 2 3 4 5 6
字母 a b d d e e f

  例子二

  有这样的一组数字: 

   当我们遍历之后得到该范围内每个数字的出现次数:

数字 7, 8 9 10 11
出现次数 1 2 1 0 1

  当我们按照每个数字出现的次数由大到小排序之后:

0 1 2 3 4
数字 7 8 8 9 11

三、算法实现

  对于数字排序的过程加以说明:

  上面的数字中,我们找到数字的最大值与最小值,这样获得了排序的元素范围以及大小

  我们可以看到: 

int  max=11, min=7 ;
View Code

  随后我们设置一个大小为 size= max-min+1 的数组,用来记录每一个元素出现的次数。

  接着就是遍历整个数组,获得元素出现的次数。

  之后按照出现次数以及元素的顺序重新排列即可。

四、代码实现

  这里的代码实现用的是这位大佬的(我觉得写的很好,所以就不写啦。)

  链接:https://blog.csdn.net/KKnick1/article/details/99735120

 private int[] countSort(int arry[]) {
        //获得数组的最大值和最小值
        int min = arry[0], max = arry[0];
        for (int i = 0; i < arry.length; i++) {
            if (arry[i] > max) {
                max = arry[i];
            }
 
            if (arry[i] < min) {
                min = arry[i];
            }
        }
 
        //对于原始数组的出现的每一个元素计数
        int size = max - min + 1;
        int[] arryCount = new int[size];
        for (int i = 0; i < arry.length; i++) {
            arryCount[arry[i] - min]++;
        }
 
        //排序
        int size1 = 0;
        int[] sortedArray = new int[arry.length];
        for (int i = 0; i < arryCount.length; i++) {
            for (int j = 0; j < arryCount[i]; j++) {
                arry[size1] = min + i;
                size1++;
            }
        }
        return sortedArray;
    }

  在这里说明一下,在扫描计数的时候:

  我们认为记录数据出现次数的数组:秩为0的位置对应数字min,这样他们的秩与数字的对应关系就是: a[i]  对应 i + min

五、适用条件

  1、如果需要排序的元素种类不是太多,可以使用

  2、不适用于小数

  复杂度: O(n + k) 其中n是待排序数据规模, k 是需要排序字符种类数目,也就是另外开辟的记录数据出现次数的数组大小。

猜你喜欢

转载自www.cnblogs.com/fantianliang/p/11878914.html