每一个桶(bucket)代表一个区间范围,里面可以承载一个或多个元素。
第一步
就是创建这些桶,并确定每一个桶的区间范围。
我们这里创建的桶数量等于原始数列的元素数量,
第二步
遍历原始数列,把元素对号入座放入各个桶中。
第三步
对每个桶内部的元素分别进行排序(显然,只有第1个桶需要排序)。
第四步
遍历所有的桶,输出所有元素。
JAVA实现
package mysort.bucketSort;
import java.util.*;
public class bucketSort {
public static double[] buckSort(double[] array){
//1.得到数列的最大值和最小值,并算出差值d
double max = array[0];
double min = array[0];
for (int i=1;i<array.length;i++){
if(array[i]>max){
max = array[i];
}
if(array[i]<min){
min = array[i];
}
}
double d = max-min;
//2.初始化桶(创建的桶数量bucketNum等于原始数列的元素数量)
int bucketNum = array.length;
//所有的桶都保存在ArrayList集合中,每一个桶都被定义成一个链表(LinkedList<Double>),这样便于在尾部插入元素
ArrayList<LinkedList<Double>> bucketList = new ArrayList<LinkedList<Double>>(bucketNum);
for (int i = 0;i<bucketNum;i++){
bucketList.add(new LinkedList<Double>());
}
//3.遍历原始数组,将每个元素放入桶中
for (int i=0;i<array.length;i++){
//(array[i]-min)*(bucketNum-1)/d这个公式可以将当前元素找到对应的桶下标
int num = (int)((array[i]-min)*(bucketNum-1)/d);
bucketList.get(num).add(array[i]);
}
//4.对每个桶内部进行排序
//使用了JDK的集合工具类Collections.sort来为桶内部的元素进行排序。
for (int i =0;i<bucketList.size();i++){
Collections.sort(bucketList.get(i));
}
//5.输出全部元素
double[] sortArray = new double[array.length];
int index = 0;
for (LinkedList<Double> list: bucketList){
for (double e:list){
sortArray[index] = e;
index++;
}
}
return sortArray;
}
public static void main(String[] args) {
double [] array = new double[]{4.5,0.84,3.25,2.18,0.5};
double[] sortArray = buckSort(array);
System.out.println(Arrays.toString(sortArray));
}
}
这里注意:(array[i]-min)*(bucketNum-1)/d这个公式可以将当前元素找到对应的桶下标
公式就是用
推导出来的
桶排序的存储结构:
桶排序时间复杂度和空间复杂度都是O(n)