前言
最近在学数据结构与算法,在此做一下记录,方便时不时复习一下。如果有什么做得不对的地方,恳请指出,万分感谢。
简述
桶排序的工作原理:假设输入数据服从均匀分布,利用某种函数的映射关系将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或者是以递归方式继续使用桶排序)。桶排序利用函数的映射关系,减少了几乎所有的比较关系。实际上,桶排序的f(k)值的计算,其作用就相当于快排中的划分,已经把大量数据分割成了基本有序的数据块(桶),然后只需要对桶中的少量数据做排序即可。
步骤
1.判断数组是否为空或数组大小是否小于2,满足则return;
2.定义最大值max,最小值min,用于获得桶的数量以及分配数据;
3.计算桶的数量bucketCount;
4.构建桶bucketArr及存放最终数据的集合resultArr;
5.将原数组中的数据分配到桶中;
6.遍历所有的桶,根据每个桶中允许存放不同的值bucketSize的大小做出判断;
7.bucketSize为1时,将桶bucketArr中所有的值都取出放到集合resultArr中;
8.bucketSize不为1时,先判断bucketCoun是否为1,为1时,bucketSize--,不为1时什么都不用做。然后定义一个集合temp,递归调用第一步,最后对集合temp进行遍历,将数据放到集合resultArr中。
图示
代码
public class BucketSort {
public final static int[] DATA = {34,22,47,8,15,23,4,10,33,17};
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
for (int i = 0; i < DATA.length; i++) {
arrayList.add(DATA[i]);
}
printObject(arrayList);
System.out.println("==================================");
ArrayList<Integer> dest = sort(arrayList,2);
printObject(dest);
}
/**
* 桶排序算法
* @param array
* @param bucketSize 作为每个桶所能放多少个不同的数值标识
* (比如当bucketSize==4时,这个桶里面可以放4种不同的数字,
* 但是容量不限,可以放无数个一样的数字(可以存放100个2))
* @return
*/
public static ArrayList<Integer> sort(ArrayList<Integer> array,int bucketSize) {
if (array == null || array.size() < 2) return array;
//定义最大最小值,用于获得桶的数量
int max = array.get(0),min = array.get(0);
//找到最大最小值
for (int i = 0; i < array.size(); i++) {
if (array.get(i) > max)
max = array.get(i);
if (array.get(i) < min)
min = array.get(i);
}
//计算桶的数量
int bucketCount = (max - min) / bucketSize + 1;
System.out.println("桶的个数为:" + bucketCount + "个");
//构建桶
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketCount);
ArrayList<Integer> resultArr = new ArrayList<>();
for (int i = 0; i < bucketCount; i++) {
bucketArr.add(new ArrayList<Integer>());
}
//将原数组中的数据分配到桶中
for (int i = 0; i < array.size(); i++) {
bucketArr.get((array.get(i) - min) / bucketSize).add(array.get(i));
}
//查看一下桶的分布情况
for (int i = 0; i < bucketArr.size(); i++) {
System.out.print("第"+i+"个桶中的数据为:");
printObject(bucketArr.get(i));
}
//遍历所有的桶,根据桶中个数做出判断
System.out.println("bucketSize为:" + bucketSize);
for (int i = 0; i < bucketCount; i++) {
if (bucketSize == 1) {
for (int j = 0;j < bucketArr.get(i).size();j++) {
resultArr.add(bucketArr.get(i).get(j));
}
}else {
if (bucketCount == 1) bucketSize--;
//对桶中的数据再用次用桶进行排序
ArrayList<Integer> temp = sort(bucketArr.get(i),bucketSize);
for (int j = 0;j < temp.size();j++) {
resultArr.add(temp.get(j));
}
}
}
return resultArr;
}
public static void printObject(ArrayList<Integer> array) {
for (int i : array) {
System.out.print(i+" ");
}
System.out.println("");
}
}