桶排序

本文深入解析桶排序算法,介绍其思路、代码实现、复杂度分析、稳定性及优势,并探讨其适用场景,尤其适合小范围大量分布均匀的小数排序。

思路

非整形的计数排序,将数放到桶内,先将桶内排序,再整体排序。

k 个桶,最后一个桶用来放最大值,只有 k - 1 个跨度,这 k - 1 个跨度对应 k - 1 个桶。
所以跨度为 (max - min)/(k - 1)

数对应的桶的下标为 (int)(arr[i] - min)/跨度

1.遍历原始数组 arr 找到最大值和最小值,确定桶数 k
2.创建 bucketList(ArrayList),往 bucketList 里添加 k 个 LinkedList,代表 k 个桶
3.遍历 arr,将数放入对应的桶内
4.对桶内的数做排序(可以使用JDK的集合工具类Collections.sort,时间复杂度O(nlogn))
5.遍历所有的桶,输出结果

代码

public class BucketSort{
    public static double[] bucketSort(double[] arr) {
       double min = arr[0];
       double max = arr[0];
       for(int i = 1; i < arr.length; i++){
           if(arr[i] < min)
               min = arr[i];
           if(arr[i] > max)
               max = arr[i];
       }
       double d = max - min;
       int k = arr.length;

        ArrayList<LinkedList<Double>> bucketList= new ArrayList<>(k);
        for(int i = 0; i < k; i++)
            bucketList.add(new LinkedList<>());

        for(int i = 0; i < arr.length; i++){
            bucketList.get((int)((arr[i]-min)*(k-1)/d)).add(arr[i]);
        }

        for(LinkedList list : bucketList)
            Collections.sort(list);

        double[] sortedArr = new double[arr.length];
        int index = 0;
        for(LinkedList<Double> list : bucketList)
            for(double e: list)
                sortedArr[index++] = e;

        return sortedArr;
    }

    public static void main(String[] args){
        double[] array = new double[]{5.1,5.9,8.7,6.33,6.56,3.9,9.1,2.78,1.33,4.6,7.5};
        double[] sortedArr = bucketSort(array);
        System.out.println(Arrays.toString(sortedArr));
    }
}

复杂度分析

时间复杂度

第1、3、5步 O(n),第2步 O(k),第4步平均 O(n/k*log(n/k)*k),共 O(n + k + n*log(n/k))
假如 n = k,时间复杂度为 O(n)
最差的情况:第一个桶装了 n - 1 个数,时间复杂度 O(nlogn)

空间复杂度

不考虑返回数组的长度
k 个桶加 n 个数占用的空间 O(n+k)

稳定性分析

Collections.sort 是稳定的,桶排序也稳定

优势

特定情况下比快速排序还快,而且还是稳定的

适用场景

小范围内的大量分布较均匀的小数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值