小白初识 计数排序(CountingSort)

计数排序,属于桶排序特殊的一种。

当要排序n个数据的时候,如果所处的范围不大,我们可以取其中的最大值K,并将数据分散在K个桶里面,

每个桶里面的数据都是相同的(这样省去了桶内排序的时间),然后顺序取出就好啦。

当然计数排序说起来简单,写起来有些地方不好理解。

 

比如我们现在有2,5,3,0,2,3,0,3这8个数,要对它排序,我们就可以先取到它的最大值5,然后确定范围在0-5,

我们申请一个0-5的内存空间去分别计算每个位置对应的每个数的个数。

下图表示的就是0-5这个内存空间的数据,我们可以看到其中0出现了两次,1出现了0次,2出现了两次,3出现了三次,4出现了0次,5出现了一次。

同时还可以总结一些规律出来,比如我们现在看到c[2]这个位置,2出现了两次,在2前面c[0] + c[1]总共有2个元素,所以c[2]对应这两个2在原数组中

的位置是2,3,我们可以得出规律c[2]所在位置 = c[0] + c[1],后面的c[3]的位置 = c[2] + c[1],我们就这样挨着顺序求和:

然后我们扫描原数组2,5,3,0,2,3,0,3,每遇到一个数,就将该数代入c数组的索引中取出当前元素在排序之后真正的索引。

我的Java实现如下:

 1 package com.structure.sort;
 2 
 3 /**
 4  * @author zhangxingrui
 5  * @create 2019-01-30 13:45
 6  **/
 7 public class CountingSort {
 8 
 9     public static void main(String[] args) {
10         int[] numbers = {3, 9, 2, 1, 8, 7, 6, 10, 9};
11         // 假设数组中存储的都是非负整数
12         countingSort(numbers);
13         for (int number : numbers) {
14             System.out.println(number);
15         }
16     }
17 
18     /**
19      * @Author: xingrui
20      * @Description: 计数排序
21      * @Date: 13:57 2019/1/30
22      */
23     private static void countingSort(int[] numbers){
24         int n = numbers.length;
25         int maxNumber = numbers[0];
26         for(int i = 1; i < n; ++i){
27             if(numbers[i] > maxNumber)
28                 maxNumber = numbers[i];
29         }
30 
31         int[] r = new int[n];
32         int[] c = new int[maxNumber + 1];
33 
34         for(int i = 0; i < n; ++i){
35             c[numbers[i]]++;
36         }
37 
38         for(int i = 1; i <= maxNumber; ++i){
39             c[i] = c[i-1] + c[i];
40         }
41 
42         for (int i = n - 1; i >= 0; --i){
43             int index = c[numbers[i]];
44             r[index - 1] = numbers[i];
45             c[index]--;
46         }
47 
48         for(int i = 0; i < n; ++i){
49             numbers[i] = r[i];
50         }
51     }
52 
53 }

其中关键的代码:

1 for (int i = n - 1; i >= 0; --i){
2             int index = c[numbers[i]];
3             r[index - 1] = numbers[i];
4             c[index]--;
5         }

从c数组中取出排序之后的索引。

需要特别说明的是,文中的图片均截图极客网王争老师的专栏《数据结构与算法之美》,如有侵权,请联系我删除。

有需要的朋友也可以去订阅这个专栏,讲的挺不错的,没有视频,只有文字和音频。

原文地址:https://www.cnblogs.com/alinainai/p/10339932.html