桶排序

    private static double[] bucketSort(double[] array){
        //1.得到数列的最大值和最小值,并算出差值d
        double max=array[0];
        double min=array[0];
//        找出最大和最小值
        for (int i = 1; i < array.length; i++) {
            if(array[i] > max){
                max=array[i];
            }
            if(array[i] < min){
                min=array[i];
            }
        }
//        数组的数值范围
        double d=max-min;
        int bucketNum=array.length;//有多少个数值就有多少个桶
//        通的数组
        List<LinkedList<Double>> bucketList=new ArrayList<>();
        for (int i = 0; i < bucketNum; i++) {
            bucketList.add(new LinkedList<>());
        }
//        将每个数组元素放入桶中,
        for (int i = 0; i < array.length; i++) {
            int num= (int) ((array[i]-min) * (bucketNum-1)/d);
            bucketList.get(num).add(array[i]);
        }
//        对每个桶进行内部排序
        for (int i = 0; i < bucketList.size(); i++) {
            Collections.sort(bucketList.get(i));
        }
//        排好序的数组
        double[] sortArray=new double[array.length];
        int index=0;
        for (LinkedList<Double> list : bucketList) {
            for (Double element : list) {
                sortArray[index++]=element;
            }
        }
         return sortArray;

    }

    public static void main(String[] args) {
        double[] array = { 8.122,0.0023, 10.09, 3.0, 4.12, 2.123, 4.12, 6.421};
        double [] sortedArray = bucketSort(array);
        System.out.println(Arrays.toString(sortedArray));
    }

假设原始数列有n个元素,分成m个桶(我们采用的分桶方式 m=n),平均每个桶的元素个数为n/m。

下面我们来逐步分析算法复杂度:

 

第一步求数列最大最小值,运算量为n。

第二步创建空桶,运算量为m。

第三步遍历原始数列,运算量为n。

第四步在每个桶内部做排序,由于使用了O(nlogn)的排序算法,所以运算量为 n/m * log(n/m ) * m。

第五步输出排序数列,运算量为n。

 

加起来,总的运算量为 3n+m+ n/m * log(n/m ) * m = 3n+m+n(logn-logm) 。

去掉系数,时间复杂度为:

O(n+m+n(logn-logm)) 

 

至于空间复杂度就很明显了:

空桶占用的空间 + 数列在桶中占用的空间 = O(m+n)

桶排序存在如下缺点

如果桶内元素分布极不均衡,极端情况下第一个桶中有n-1个元素,最后一个桶中有1个元素,此时的时间复杂度将退化成O(nlogn)还白白创建了许多空桶

c79e4c0047df3874f76ae5293be69682482.jpg

在这种情况下,个人建议用归并或快排代替

转载于:https://my.oschina.net/u/3574106/blog/3062571

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值