计数排序:的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
pom.xml
org.springframework.boot spring-boot-starter 2.6.0 org.projectlombok lombok 1.16.14
假设我们要排序的数据是:15, 8, 23, 38, 28, 19, 32, 21, 9
通过我们的整体流程图,来看看数据是怎么分,又是怎么合成的。
桶编号 = (数组元素 - 最小值) * (桶个数 - 1) / (最大值 - 最小值)
数组索引 | 数组数据 | 计算桶编号 |
---|---|---|
0 | 15 | (15−8)∗(4−1)(38−8)=0\frac{(15 - 8) * (4 - 1)}{(38 - 8)}=0(38−8)(15−8)∗(4−1)=0 |
1 | 8 | (8−8)∗(4−1)(38−8)=0\frac{(8 - 8) * (4 - 1)}{(38 - 8)}=0(38−8)(8−8)∗(4−1)=0 |
2 | 23 | (23−8)∗(4−1)(38−8)=1\frac{(23 - 8) * (4 - 1)}{(38 - 8)}=1(38−8)(23−8)∗(4−1)=1 |
3 | 38 | (38−8)∗(4−1)(38−8)=3\frac{(38 - 8) * (4 - 1)}{(38 - 8)}=3(38−8)(38−8)∗(4−1)=3 |
4 | 28 | (28−8)∗(4−1)(38−8)=2\frac{(28 - 8) * (4 - 1)}{(38 - 8)}=2(38−8)(28−8)∗(4−1)=2 |
5 | 19 | (19−8)∗(4−1)(38−8)=1\frac{(19 - 8) * (4 - 1)}{(38 - 8)}=1(38−8)(19−8)∗(4−1)=1 |
6 | 32 | (32−8)∗(4−1)(38−8)=2\frac{(32 - 8) * (4 - 1)}{(38 - 8)}=2(38−8)(32−8)∗(4−1)=2 |
7 | 21 | (21−8)∗(4−1)(38−8)=1\frac{(21 - 8) * (4 - 1)}{(38 - 8)}=1(38−8)(21−8)∗(4−1)=1 |
8 | 9 | (9−8)∗(4−1)(38−8)=0\frac{(9 - 8) * (4 - 1)}{(38 - 8)}=0(38−8)(9−8)∗(4−1)=0 |
根据计算把数据放到相应的桶中,如下图所示:
接下里我们对桶里的元素进行排序,我这里为了省事就采用自带的排序了,排序结果如下:
你可以使用其他任意排序算法进行(比如快速排序,插入排序等等),当然这里递归使用桶排序也是可以的。
/*** 桶排序** @param arr* @param bucketSize*/
public static void bucketsort(int[] arr, int bucketSize) {// 初始化最大最小值int max = Integer.MIN_VALUE;int min = Integer.MAX_VALUE;// 找出最小值和最大值for (int num : arr) {max = Math.max(max, num);min = Math.min(min, num);}// 创建bucketSize个桶List> bucketList = new ArrayList<>();// 声明五个桶for (int i = 0; i < bucketSize; i++) {bucketList.add(new ArrayList<>());// 确定桶的格式为ArrayList}// 将数据放入桶中for (int num : arr) {// 确定元素存放的桶号int bucketIndex = (num - min) * (bucketSize - 1) / (max - min);//重点log.info("({} - {}) * ({} - 1) / ({} - {})={}", num, min, bucketSize, max, min, bucketIndex);log.info("【{}】放入到第【】号桶中:{}", num, bucketIndex + 1);List list = bucketList.get(bucketIndex);list.add(num);// 将元素存入对应的桶中}// 遍历每一个桶for (int i = 0, arrIndex = 0; i < bucketList.size(); i++) {List list = bucketList.get(i);log.info("第【{}】桶的数据为:{}", i + 1, list);list.sort(null);// 对每一个桶排序for (int value : list) {arr[arrIndex++] = value;}}
}public static void main(String[] args) {int[] arr = {15, 8, 23, 38, 28, 19, 32, 21, 9};log.info("要排序的初始化数据:{}", arr);//从小到大排序bucketsort(arr, 4);log.info("结果为:{}", arr);
}
运行结果:
要排序的初始化数据:[15, 8, 23, 38, 28, 19, 32, 21, 9]
(15 - 8) * (4 - 1) / (38 - 8)=0
【15】放入到第【】号桶中:1
(8 - 8) * (4 - 1) / (38 - 8)=0
【8】放入到第【】号桶中:1
(23 - 8) * (4 - 1) / (38 - 8)=1
【23】放入到第【】号桶中:2
(38 - 8) * (4 - 1) / (38 - 8)=3
【38】放入到第【】号桶中:4
(28 - 8) * (4 - 1) / (38 - 8)=2
【28】放入到第【】号桶中:3
(19 - 8) * (4 - 1) / (38 - 8)=1
【19】放入到第【】号桶中:2
(32 - 8) * (4 - 1) / (38 - 8)=2
【32】放入到第【】号桶中:3
(21 - 8) * (4 - 1) / (38 - 8)=1
【21】放入到第【】号桶中:2
(9 - 8) * (4 - 1) / (38 - 8)=0
【9】放入到第【】号桶中:1
第【1】桶的数据为:[15, 8, 9]
第【2】桶的数据为:[23, 19, 21]
第【3】桶的数据为:[28, 32]
第【4】桶的数据为:[38]
结果为:[8, 9, 15, 19, 21, 23, 28, 32, 38]
上一篇:Python编程 集合
下一篇: 我的愿望作文四年级300字(经典6篇)