转自:https://blog.csdn.net/qq_27124771/article/details/87651495
https://www.jianshu.com/p/204ed43aec0c
1.基本过程
将待排序数组按照大小分别放入N个桶,然后对各桶内数据排序,之后合并。减小总的每次排序的规模,用空间换时间。
2.关键环节
元素值域的划分,也就是元素到桶的映射规则。映射规则需要尽量保证元素分散均匀,否则当所有数据集中在同一个桶中时,桶排序失效。
排序算法的选择。桶排序算法的复杂度和稳定性,都根据选择的排序算法不同而不同。
上面两个链接中给出的映射规则不同:其中一个是min/10作为间隔大小,另一个是:(max - min) / arr.length + 1。所以可以根据数据的情况来选择不同的映射规则。
3.复杂度
O(N),//还有待我分析
4.代码
public static void bucketSort(int[] arr){ // 计算最大值与最小值 int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; for(int i = 0; i < arr.length; i++){ max = Math.max(max, arr[i]); min = Math.min(min, arr[i]); } // 计算桶的数量 int bucketNum = (max - min) / arr.length + 1; ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum); for(int i = 0; i < bucketNum; i++){ bucketArr.add(new ArrayList<Integer>()); } // 将每个元素放入桶 for(int i = 0; i < arr.length; i++){ int num = (arr[i] - min) / (arr.length); bucketArr.get(num).add(arr[i]); } // 对每个桶进行排序 for(int i = 0; i < bucketArr.size(); i++){ Collections.sort(bucketArr.get(i)); } // 将桶中的元素赋值到原序列 int index = 0; for(int i = 0; i < bucketArr.size(); i++){ for(int j = 0; j < bucketArr.get(i).size(); j++){ arr[index++] = bucketArr.get(i).get(j); } } }