java实现桶排序

桶排序是指:将待排序数组中的元素划分为多个桶(范围段),对每个桶分别进行排序,将多个桶组合即为排序结果。

桶排序的时间复杂度为O(n + c),  其中n为待排序数据量,c = n * (logn - logm), m为桶的个数。极端情况下,当桶的个数与数据量相等时,桶排序时间复杂度为O(n)。

看一些博客里写道桶排序是稳定排序,另一些博客则说是非稳定排序。实际上,桶排序的稳定性取决于桶内排序所使用的算法,若使用插入排序,则是稳定排序,若使用快排,则是非稳定排序。

 1 import java.util.Arrays;
 2 
 3 public class BucketSort {
 4     public static void main(String[] args) {
 5         int[] array = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
 6         bucketSort(array);
 7         System.out.println(Arrays.toString(array));
 8     }
 9 
10     public static void bucketSort(int[] arr) {
11         if (arr == null || arr.length == 0) {
12             return;
13         }
14         int len = arr.length;
15         // 根据原始序列的长度,设置桶的数量。这里假设每个桶放最多放4个元素
16         int bucketCount = len / 4;
17         // 遍历原始序列,找出最大值和最小值
18         int min = 0, max = 0;
19         for (int i = 0; i < len; i++) {
20             if (arr[i] > max) {
21                 max = arr[i];
22             } else if (arr[i] < min) {
23                 min = arr[i];
24             }
25         }
26         // 每个桶的数值范围
27         int range = (max - min + 1) / bucketCount;
28         int[][] buckets = new int[bucketCount][];
29         // 遍历原始序列
30         for (int i = 0; i < len; i++) {
31             int val = arr[i];
32             // 计算当前值属于哪个桶
33             int bucketIndex = (int) Math.floor((val - min) / range);
34             // 向桶中添加元素
35             buckets[bucketIndex] = appendItem(buckets[bucketIndex], val);
36         }
37         // 最后合并所有的桶
38         int k = 0;
39         for (int[] b : buckets) {
40             if (b != null) {
41                 for (int i = 0; i < b.length; i++) {
42                     arr[k++] = b[i];
43                 }
44             }
45         }
46     }
47 
48     private static int[] appendItem(int[] bucketArr, int val) {
49         if (bucketArr == null || bucketArr.length == 0) {
50             return new int[]{val};
51         }
52         // 拷贝一下原来桶的序列,并增加一位
53         int[] arr = Arrays.copyOf(bucketArr, bucketArr.length + 1);
54         // 这里使用插入排序,将新的值val插入到序列中
55         int i;
56         for (i = arr.length - 2; i >= 0 && arr[i] > val; i--) {
57             // 从新序列arr的倒数第二位开始向前遍历(倒数第一位是新增加的空位,还没有值)
58             // 如果当前序列值大于val,那么向后移位
59             arr[i + 1] = arr[i];
60         }
61         arr[i + 1] = val;
62         return arr;
63     }
64 }

 

posted @ 2019-09-28 18:40  开坦克的舒克  阅读(1548)  评论(0编辑  收藏  举报