排序算法之桶排序【Java版】

引言

本篇是排序算法的第八篇,桶排序,桶排序是计数排序的升级版。

1、算法步骤

1、设定一个基准,将待排序的数字按照一定范围,从小到大的平均分在N个桶中,此时桶已经排好序,桶中的元素还未排序;
2、将桶中的元素进行排序。
3、将每个桶按照从小到大的编号,依次取出里面的元素放入到待排序数组中,排序完成。

2、时间复杂度

平均时间复杂度O(n + k)

3、算法实现

public class BucketSort {

    public static void main(String[] args) {
        int[] numbers = {12,2,24,30,6,16};
        int[] result = BucketSort.bucketSort(numbers,3);
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < result.length; i++) {
            stringBuffer.append(result[i] + " ");
        }
        System.out.println(stringBuffer.toString());
    }

    //bucketSize是初始化桶个数的一个基准值
    public static int[] bucketSort(int[] arg,int bucketSize){
        if(arg.length == 0){
            return arg;
        }
        int maxValue = arg[0];
        int minVaule = arg[0];
        for (int i = 1; i < arg.length; i++) {
            if(arg[i] < minVaule){
                minVaule = arg[i];
            } else if(arg[i] > maxValue){
                maxValue = arg[i];
            }
        }
        //桶的数量
        int bucketCount = (int)Math.floor((maxValue - minVaule) / bucketSize) + 1;
        //初始化一个二维数组,横坐标是桶的编号,纵坐标是值
        int[][] buckets = new int[bucketCount][0];
        //将待排序值按照一定规则映射到数组中
        for (int i = 0; i < arg.length; i++) {
            int index = (int)Math.floor((arg[i] - minVaule) / bucketSize);
            buckets[index] = arrAppend(buckets[index], arg[i]);
        }
        int arrIndex = 0;
        //循环每个桶
        for (int i = 0; i < buckets.length; i++) {
            if(buckets[i].length <= 0){
                continue;
            }
            //将每个桶中的数组按照插入排序算法进行排序
            int[] bucket = insertSort(buckets[i]);
            //按照桶的顺序,将桶中排好序的值,依次放入到数组中
            for (int j = 0; j < bucket.length; j++) {
                arg[arrIndex++] = bucket[j];
            }
        }
        return arg;
    }
    //插入排序算法
    public static int[] insertSort(int[] arr){
        for (int i = 1; i < arr.length; i++) {
            // 记录要插入的数据
            int tmp = arr[i];
            // 从已经排序的序列最右边的开始比较,找到比其小的数
            int j = i;
            while (j > 0 && tmp < arr[j - 1]) {
                arr[j] = arr[j - 1];
                j--;
            }
            // 存在比其小的数,插入
            if (j != i) {
                arr[j] = tmp;
            }
        }
        return arr;
    }
    //自动扩容,并保存数据
    public static int[] arrAppend(int[] arr,int value){
        arr = Arrays.copyOf(arr, arr.length + 1);
        arr[arr.length - 1] = value;
        return arr;
    }
}

结束语

桶排序的高效与否的关键就在于这个映射函数的确定,在空间足够的时候,尽量增加桶的数量,将数据尽量均匀的分到K个桶中。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值