来源百度百科
桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是 比较排序,他不受到 O(n log n) 下限的影响。
一、基本思想
桶排序,顾名思义,会用到桶。核心思想就是将要排序的数组分到几个有序的桶中,每个桶里的数据再单独进行排序。桶内排序完之后,再把数据从桶中依次取出来,组成的序列就是有序的了。
二、过程
- 先根据实际生产计算桶的个数
- 把数据放入固定的桶中
- 将每个桶中的数据进行排序
- 将每个桶中的数据依次取出,放在数组中,即为有序
三、总结
进行桶排序有以下几点需要注意:
- 要排序的数据要很容易分为m个桶
- 桶与桶之间要有天然的大小顺序(为了桶与桶之间不用排序)
代码:
/**
* 桶排序
* @Author: Han-YLun
* @date 2019/4/25
* @Version 1.0
*/
public class BucketSort {
//桶的个数
private static int num;
//数组中的最大最小值
private static int min,max;
/**
* 进行桶排序
* @param arr 需要进行桶排序的数组
*/
public static void bucketSort(int[] arr){
if(arr.length < 2)
return;
int pos;
int i,j,k;
//提前获取数组元素,防止时间消耗
int len = arr.length;
max = min = arr[0];
for ( i = 0; i <len ; i++) {
if (arr[i] > max){
max = arr[i];
}else if(arr[i] < min){
min = arr[i];
}
}
//通过最大最小值获取桶的个数(可根据实际生产自定义算法计算桶的个数)
num = (max - min + 1) / 10 + 1;
//保存所有桶
List<ArrayList<Integer>> buckets = new ArrayList<ArrayList<Integer>>(num);
//初始化每个桶
for ( i = 0; i < num; i++) {
buckets.add(new ArrayList<Integer>());
}
for (int data : arr) {
//计算桶的索引并且添加到相应的桶中
k = getBucketIndex(data - min + 1 ) / 10;
buckets.get(k).add(data);
}
pos = 0;
//对每个桶进行快排,然后加排序后的元素重新放回数组中
for ( i = 0; i < num; i++) {
int size = buckets.get(i).size();
int[] temp = new int[size];
for (j = 0; j < size; j++) {
temp[j] = buckets.get(i).get(j);
}
QuickSort.quickSortInternally(temp,
0,size-1);
for (j = 0; j < size; j++) {
arr[pos++] = temp[j];
}
}
}
/**
* 根据数组计算对应的桶
* @param data
* @return
*/
private static int getBucketIndex(int data) {
return (data - min + 1);
}
}
四、快速排序的优化
- 在额外空间足够的情况下,尽量增加桶的个数
- 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中
五、结论
- 当输入的数据可以均匀的分配到每个桶中时,此时最快
- 当输入的数据被分配到了同一个桶中,此时最慢
- 桶排序适用于外部排序中
- 当桶的个数m越接近于数据的个数n为,复杂度为O(n)
- 当所有的数据都被分配到一个桶中时,就退化成O(nlogn)的排序算法
- 桶内数据的排序可以使用快速排序
如果文章有错的地方欢迎指正,大家互相交流。