桶排序详解

1、什么是桶排序?

        桶排序从整体来看也是一个非比较排序,是计数排序的升级版,其主要是先把序列中的数据划分为一个个的范围,每个范围相当一个桶,将数据放入桶中,每个桶分别进行排序,然后取出拼接即可计数排序不适用于序列中max-min范围较广或者序列中的数据不是整数的情况,但是桶排序没有这些限制,其主要步骤是将数据放入桶中,桶中的数据自己排序。

2、桶排序的应用场景

        桶排序适用于序列中元素的分布比较均匀的场景,这样其划分的每个桶中的数据比较均匀,排序较快,如果不均匀会导致数据被分配到一个桶里面,这会使其他的桶没用,其消耗的时间就主要靠这个桶所使用的排序算法了。

3、桶排序的思想

        桶排序的思想是:将数据放入桶中,每个桶中的元素分别进行排序,其实就是一种用空间换时间的算法,还包含一种分治思想。        

4、桶排序的步骤

步骤:
        1、取序列中的最大值max和最小值min,取桶的个数 为(max-min)/arr.length+1个桶,桶的 范围是arr.length,其中的加1是为解决桶是(arr[i]-min)/arr.length作为索引,则当是最大值时,最大索引是(arr[i]-min)/arr.length,则总的数量为(arr[i]-min)/arr.length+1。
        2、遍历序列,则将其放入到(arr[i]-min)/arr.length的桶中
        3、每个桶中的元素分别做快速排序
        4、遍历所有的桶,则完成了排序

5、桶排序的Java代码

public class BucketSort {

    /**
     * 桶排序
     * @param args
     */
    public static void main(String[] args) {
        int[] arr = {10, 0, 80, 40, 90, 22, 60, 30, 55, 77, 80, 50};
        buckSort(arr);
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }

    private static void buckSort(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }
        int min = arr[0];
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (min > arr[i]) {
                min = arr[i];
            }
            if (max < arr[i]) {
                max = arr[i];
            }
        }
        // 桶数量,桶的范围是arr.length,注意桶的范围是自定义的
        int buckNum = (max - min) / arr.length + 1;
        List<List<Integer>> list = new ArrayList<>(buckNum);
        for (int i = 0; i < buckNum; i++) {
            list.add(new ArrayList<>());
        }
        // 将元素放入桶中
        for (int i = 0; i < arr.length; i++) {
            int index = (arr[i] - min) / arr.length;
            List<Integer> integers = list.get(index);
            integers.add(arr[i]);
        }

        for (List<Integer> integers : list) {
            if (integers == null || integers.size() == 0) {
                continue;
            }
            // 使用归并排序
            Collections.sort(integers);
        }
        int i = 0;
        for (List<Integer> integers : list) {
            if (integers == null || integers.size() == 0) {
                continue;
            }
            for (Integer integer : integers) {
                arr[i++] = integer;
            }
        }
    }

}

6、桶排序的总结

        桶排序时间复杂度是O(n+m+n(logn-logm)),空间复杂度是O(m+n), 稳定主要看桶中选取的排序算法。
        时间复杂度是O(n+m+n(logn-logm)):上面的代码时间消耗为n+m+n+(n/m*logn/m)*m + n,去掉系数为O(n+m+n(logn-logm)),当n=m时,时间复杂度是O(n),当选取桶不当时,所有数据在一个桶中,则是桶所选取的算法的时间复杂度。
        空间复杂度是O(m+n):上面集合的内存是m+n
        稳定主要看桶中选取的排序算法:因为相同元素会被分配到同一个桶,所以同一个桶所使用的算法不同,则其稳定性不同,本文使用的是归并算法排序,是稳定的。

7、桶排序的类比

        桶排序的重点是:将数据放入桶,桶里面进行排序,类似于:中考将不同分数段的学生分到不同的学校,学校中相同范围的学生进行成绩排名。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值