桶排序(bucket sort)假设输入数据服从均匀分布。平均情况下他的时间代价是O(n)。
计数排序假设输入数据分布于一个小区间的整数,而桶排序则假设输入是一个随机过程产生的,该过程将元素均匀独立地分布于[0,1)区间上。 1.桶排序的基本思想 桶排序将[0,1)区间划分为n个相同的大小的子区间,这些子区间被称为桶。然后将n个输入元素分别放入各自的桶中。因为输入时均匀独立的,所以一般不会有很多数同时落在一个桶中的情况。这样,我们想对各个桶中的数据进行排序,然后遍历每个桶,按照次序把各个桶中的元素列出来即可。 一个桶排序的示例如图:
简单来说就是把数组 arr 划分为n个大小相同子区间(桶),每个子区间各自排序,最后合并。
这样说是不是和分治法有点像了 啊!因为分治法就是分解 —— 解决 ——合并这样的套路。我认为这样想没毛病。可以理解为桶排序是一种特殊的分治法,特殊的地方主要体现在前两部分(这样说不知道对不对~)。
具体来说如下: 分解部分,采用了计数排序类似的思想,通过分解,虽然没有比较,但是将数据基本按照大小划分了几个区间。
针对输入数据均匀分布的特点,因此将数据分布的区间可以均匀分为n个子区间。
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* 桶排序(bucket sort)假设输入数据服从均匀分布。平均情况下他的时间代价是O(n)。
* 计数排序假设输入数据分布于一个小区间的整数,而桶排序则假设输入是一个随机过程产生的,该过程将元素均匀独立地分布于[0,1)区间上。
* 1.桶排序的基本思想
* 桶排序将[0,1)区间划分为n个相同的大小的子区间,这些子区间被称为桶。然后将n个输入元素分别放入各自的桶中。
* 因为输入时均匀独立的,所以一般不会有很多数同时落在一个桶中的情况。这样,我们想对各个桶中的数据进行排序,
* 然后遍历每个桶,按照次序把各个桶中的元素列出来即可。
* 简单来说就是把数组arr划分为n个大小相同子区间(桶),每个子区间各自排序,最后合并。
* 这样说是不是和分治法有点像了啊!因为分治法就是分解(分桶) —— 解决(排序) ——合并这样的套路
*/
public class BucketSort {
// public static void bucketSort(int[] A) {
// //1. 构造桶
// //1.1 确定桶的个数n
// int n = A.length;
// //1.2 声明并初始化一个List,存放链表;
// List<ArrayList<Integer>> Blist = new ArrayList<>(n);
// for(int i = 0; i < n; i++)
// Blist.add(new ArrayList<Integer>());
// //2.将数组中的元素放到桶中
// //2.1 确定元素的最值
// int max = Integer.MIN_VALUE;
// int min = Integer.MAX_VALUE;
// for(int a : A){
// max = Math.max(max, a);
// min = Math.min(min, a);
// }
// //2.2 确定每个元素放入桶的编号并放进去
// for(int i : A){
// //2.2.1 确定桶的编号
// int len = A.length;
// //加1是为了保证inde< A.length,防止程序抛出IndexOutofBoundsEx;
// int index = (int)((i-min) / (max-min+1.0) * A.length);
// //2.2.2 放入对应的桶中
// Blist.get(index).add(i);
// }
// //3.桶内排序
// for(int i = 0; i < Blist.size(); i++){
// java.util.Collections.sort(Blist.get(i));
// }
// //4.合并数据
// int j = 0;
// for(ArrayList<Integer> arr : Blist){
// for(int i : arr){
// A[j++] = i;
// }
// }
// }
//第二种分桶的方法
public static void bucketSort(int[] arr){
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for(int i = 0; i < arr.length; i++){
max = Math.max(max, arr[i]);
min = Math.min(min, arr[i]);
}
//桶数
int bucketNum = (max - min) / arr.length + 1;
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>();
for(int i = 0; i < bucketNum; i++){
bucketArr.add(new ArrayList<Integer>());
}
//将每个元素放入桶
for(int i = 0; i < arr.length; i++){
int num = (arr[i] - min) / (arr.length);
bucketArr.get(num).add(arr[i]);
}
//对每个桶进行排序
for(int i = 0; i < bucketArr.size(); i++){
Collections.sort(bucketArr.get(i));
}
//合并数据
int j = 0;
for(ArrayList<Integer> arrTemp : bucketArr){
for(int i : arrTemp){
arr[j++] = i;
}
}
}
public static void main(String[] args) {
int A[]={2,5,3,30,2,3,0,6,7,2,1,4,3,20};
BucketSort.bucketSort(A);
System.out.println(Arrays.toString(A));
}
}
https://blog.csdn.net/sunjinshengli/article/details/70738527

1316

被折叠的 条评论
为什么被折叠?



