欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

小白初识 - 计数排序(CountingSort)

程序员文章站 2022-11-13 21:09:54
计数排序,属于桶排序特殊的一种。 当要排序n个数据的时候,如果所处的范围不大,我们可以取其中的最大值K,并将数据分散在K个桶里面, 每个桶里面的数据都是相同的(这样省去了桶内排序的时间),然后顺序取出就好啦。 当然计数排序说起来简单,写起来有些地方不好理解。 比如我们现在有2,5,3,0,2,3,0 ......

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

当要排序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出现了一次。

小白初识 - 计数排序(CountingSort)

同时还可以总结一些规律出来,比如我们现在看到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],我们就这样挨着顺序求和:

小白初识 - 计数排序(CountingSort)

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

小白初识 - 计数排序(CountingSort)

 

我的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数组中取出排序之后的索引。

 

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

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

小白初识 - 计数排序(CountingSort)