算法导论之桶排序

桶排序(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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值