思想:正如网上大部分文章所说,桶排序就是把原始数组的数据防放入各个桶中。然后对桶再排序,然后把每个桶的数据依次输出到原始数组就可以了,我自己写了个简陋版本的,不求效率,只求简易实现。我自己写这个效率很低,有时间再改进吧。。
public class BucketSort {
@Autowired
private ShellSort shellSort;
public static void main(String[] args) {
int[] arr = new int[100]; //构建一个空的一维数组
for (int i = 0; i < arr.length; i++) {
int temp = (int) (Math.random() * 1000) + 1;//随机产生一个 1~10 的整数
arr[i] = temp;//将产生的数添加到数组
}
long a = System.currentTimeMillis();
int[] array = busketSort(arr,10);
long b = System.currentTimeMillis();
System.out.println(b - a + "毫秒");
for (int i = 0; i < arr.length; i++) {
System.out.println(array[i]);
}
}
// 数组 和桶的个数
public static int[] busketSort(int[] array,int count) {
// 初始化桶 利用二维数组 我这里每一个桶长度都等于原来数组长度,所以效率低,之所以是这样,是因为我还没找到一种
// 如何得知每个桶数据的大小,所以都给他们设为最大值。
int[][] bucketArray = new int[count][ array.length];
for (int i = 0; i < array.length; i++) {
// 得到数据在哪个桶
int index = getIndex(array[i],count);
// 把数据存进对应的桶
bucketArray[index][i] = array[i];
}
// 对桶进行排序
int[] ints = sort1(bucketArray, array);
return ints;
}
public static int[] sort1(int[][] bucketArray, int[] array) {
for (int i = 0; i < bucketArray.length; i++) {
// 取对应的桶
int[] ints = bucketArray[i];
//调用希尔排序对每个桶排序 希尔排序可以参考我另一篇文章 这里不贴代码了
ShellSort.sort(ints);
}
//组装数据
int index = 0;
// 一维数组 代表列
for (int i = 0; i < bucketArray.length; i++) {
// 二维数组 代表行
for (int j = 0; j < bucketArray[i].length; j++) {
// 若数组有值 则存进去 这里会有数据损失 0不会存进去 有待优化
if (bucketArray[i][j] > 0) {
array[index] = bucketArray[i][j];
index++;
}
}
}
return array;
}
// 根据桶的容量和数组中最小值求得数据在哪个桶
public static int getIndex(int a, int min, int capacity) {
//
return (a - min) / capacity;
}
}
思考桶排序的关键点:
1.在于如何确定桶的个数以及每个桶所存储的数据量。每个桶的容量应该是相同的
公式如下:
桶的个数*桶的容量大于等于数组中的最大值-最小值 桶之间的间距和桶的容量相等。
// 根据桶的容量和数组中最小值求得数据在哪个桶
public static int getIndex(int a, int min, int capacity) {
//
return (a - min) / capacity;
}
// 根据桶的容量求得桶的数量
public static int getBucketCount(int[] array, int capacity, int max, int min) {
// 桶的个数*桶的容量大于等于数组中的最大值-最小值 桶之间的间距和桶的容量相等。
int count = 0;
return count = (max - min) / capacity + 1;
}
// 根据桶的数量求得桶的容量
public static int getBucketLength(int[] array, int count, int max, int min) {
// 桶的个数*桶的容量大于等于数组中的最大值-最小值 桶之间的间距和桶的容量相等。
int capacity = 0;
return capacity = (max - min) / count + 1;
}
维基百科桶排序:
利用ArrayList来对数据排序,
public static void main(String[] args) {
int[] arr = new int[10]; //构建一个空的一维数组
for (int i = 0; i < arr.length; i++) {
int temp = (int) (Math.random() * 100) + 1;//随机产生一个 1~10 的整数
arr[i] = temp;//将产生的数添加到数组
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("----------------------------------");
long a = System.currentTimeMillis();
int[] array = busketSort(arr, 10);
long b = System.currentTimeMillis();
System.out.println(b - a + "毫秒");
for (int i = 0; i < arr.length; i++) {
System.out.println(array[i]);
}
}
// 数组 和桶的个数
public static int[] busketSort(int[] array, int count) {
int max = array[0], min = array[0];
for (int i = 0; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
if (array[i] < min) {
min = array[i];
}
}
// 初始化创建桶
List bucketList = new ArrayList<List<Integer>>();
for (int i = 0; i < count; i++) {
//根据count 创建桶的个数
bucketList.add(new ArrayList<Integer>());
}
for (int i = 0; i < array.length; i++) {
// 得到数据应该在哪个桶
int index = getIndex(array[i], min, count);
// 把数据存进对应的桶
((ArrayList<Integer>) bucketList.get(index)).add(array[i]);
}
ArrayList<Integer> bucket = null;
int index = 0;
for (int i = 0; i < count; i++) {
bucket = (ArrayList<Integer>) bucketList.get(i);
insertSort(bucket);
for (int k : bucket) {
array[index++] = k;
}
}
return array;
}
// 把桶內元素插入排序
private static void insertSort(List<Integer> bucket) {
for (int i = 1; i < bucket.size(); i++) {
int temp = bucket.get(i);
int j = i - 1;
for (; j >= 0 && bucket.get(j) > temp; j--) {
bucket.set(j + 1, bucket.get(j));
}
bucket.set(j + 1, temp);
}
}