桶排序(箱排序)
定义
桶排序的工作原理是将数组分到有限数量的桶中,每个桶再个别排序
有可能使用别的排序算法或者以递归方式继续使用桶排序进行排序
稳定性
稳定
时间复杂度
平均时间复杂度:O(N + C)
C = N * (logN-logM)
N为待排数据,M为桶数量
当N=M时,最好效率达到O(N)
适用场合
两个必要条件:
- 最大最小值相差较大
- 数据分布均匀,否则可能将数据集中到同一个桶中,便失去了桶排序的意义
过程分析
桶排序的基本思想:把数组arr划分为n个大小相同的子区间(桶),每个子区间各自排序,最后合并。
计数排序是桶排序的一种特殊情况,可以把计数排序当成每个桶里只有一个元素的情况
-
找出待排序数组的最大值和最小值
-
使用动态数组ArrayList作为桶,桶中放置的元素也使用ArrayList存储。
桶的数量:(max-min)/arr.length +1
-
每个桶各自排序
-
遍历桶数组,把排好的元素放进输出数组
代码
测试用例
int arr[] = {37,18,21,21,49,0,25,6,14};
原代码
/**
* 桶排序
* @param arr
* @param len
*/
public static void bucketSort(int[] arr,int len){
// 求取最大值最小值,确定桶区间范围
// 记录数组中的最大值
int max = Integer.MIN_VALUE;
// 记录数组中的最小值
int min = Integer.MAX_VALUE;
for (int i = 0;i<len;i++){
max = Math.max(max,arr[i]);
min = Math.min(min,arr[i]);
}
System.out.println("最大值:"+max);
System.out.println("最小值:"+min);
// 桶数
int bucketNum = (max - min) / arr.length + 1;
System.out.println("桶数 " + bucketNum);
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
for (int i = 0;i<bucketNum;i++){
bucketArr.add(new ArrayList<Integer>());
}
// 把每个元素放入桶
for (int i = 0;i<len;i++){
int num = (arr[i] - min) / len;
System.out.println("num:"+arr[i]+" index of num :" + num);
bucketArr.get(num).add(arr[i]);
}
// 对每个桶进行排序
for (int i = 0;i<bucketArr.size();i++){
Collections.sort(bucketArr.get(i));
}
// 输出排序后的桶数据
System.out.println(bucketArr.toString());
//合成新数组
int i = 0;
for (ArrayList<Integer> arrItem:bucketArr){
if (arrItem.size()!=0){
for (int item:arrItem){
arr[i++]=item;
}
}
}
System.out.println(Arrays.toString(arr));
}
运行结果