Java排序算法之桶排序详解

 更新时间:2023年10月30日 09:31:57   作者:哇哈哈水有点甜  
这篇文章主要介绍了Java排序算法之桶排序详解,桶排序是将数组中的元素放到一个一个的桶中,每个桶(bucket)代表一个区间,里面可以承载一个或者多个元素,然后将桶内的元素进行排序,再按顺序遍历桶,输出桶内元素,需要的朋友可以参考下

Java排序算法之桶排序

概念:桶排序是将数组中的元素放到一个一个的桶中,每个桶(bucket)代表一个区间,里面可以承载一个或者多个元素。然后将桶内的元素进行排序,再按顺序遍历桶,输出桶内元素。

时间复杂度:O(n+m+n(logn-logm)) (n代表数组长度,m代表桶数,当n=m时,时间复杂度为O(n))

空间复杂度:O(m+n)

缺点:如果数组中除了最后一个元素全部都在第一个桶中,那么查询的时间复杂度会退化为O(nlogn),而且中间白白创建了许多空桶。

在这里插入图片描述

代码实现(java)

public static void main(String[] args) {
    double[] arr = new double[]{4.12, 6.421, 0.0023, 3.0, 2.123, 8.122, 4.12, 10.09};
    bucketSort(arr);
    for (double v : arr) {
        System.out.println(v);
    }


}


public static void bucketSort(double[] arr) {
    //1.取出数组中的最大值和最小值
    double max = Double.MIN_VALUE;
    double min = Double.MAX_VALUE;
    for (int i = 0; i < arr.length - 1; i++) {
        if (arr[i] < min) {
            min = arr[i];
        }
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    //2.初始化桶
    //桶的数量
    int bucketNum = arr.length;
    //每个桶的区间跨度
    double span = (max - min + 1) / bucketNum;
    ArrayList<LinkedList<Double>> bucketList = new ArrayList<LinkedList<Double>>(bucketNum);
    //在桶列表中添加元素个数的空桶
    for (int i = 0; i < bucketNum; i++) {
        bucketList.add(new LinkedList<Double>());
    }
    //3.遍历原始数组,将每个元素放入桶中
    for (int i = 0; i < arr.length; i++) {
        //获取桶的下标
        int num = (int) Math.floor((arr[i] - min) / span);//这里计算的结果是第几个桶,用Math.floor取到桶的下标,比如计算结果是2.5,说明应该放到第三个桶中,下标为2
        bucketList.get(num).add(arr[i]);
    }
    //4.对桶内元素进行排序
    for (int i = 0; i < bucketList.size(); i++) {
        Collections.sort(bucketList.get(i));
    }
    //5.输出全部元素
    double[] sortArray = new double[arr.length];
    int index = 0;
    for (LinkedList<Double> list : bucketList) {
        for (Double aDouble : list) {
            sortArray[index] = aDouble;
            index++;
        }
    }
}

时间复杂度:假设数组长度为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)) 当n=m时,时间复杂度可以达到O(N)

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

到此这篇关于Java排序算法之桶排序详解的文章就介绍到这了,更多相关Java桶排序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入了解Java中Volatile关键字

    深入了解Java中Volatile关键字

    这篇文章主要介绍了Java中Volatile关键字的相关知识,文章讲解非常详细,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06
  • 结合线程池实现apache kafka消费者组的误区及解决方法

    结合线程池实现apache kafka消费者组的误区及解决方法

    这篇文章主要介绍了结合线程池实现apache kafka消费者组的误区及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • Java实现TCP和UDP协议详解

    Java实现TCP和UDP协议详解

    这篇文章主要介绍了Java实现TCP和UDP协议详解,TCP(传输控制协议)和UDP(用户数据报协议)是两种最常用的传输层协议,它们都用于在网络上传输数据,但是它们之间有很多不同之处,需要的朋友可以参考下
    2023-07-07
  • Spring MVC保证Controller并发安全的方法小结

    Spring MVC保证Controller并发安全的方法小结

    在 Spring MVC 中,默认情况下,@Controller 是单例的,这意味着所有请求共享一个 Controller 实例,为确保并发安全,Spring 并不会自动对 Controller 进行线程安全保护,本文给大家介绍了Spring MVC保证Controller并发安全的方法,需要的朋友可以参考下
    2024-11-11
  • Swagger2配置Security授权认证全过程

    Swagger2配置Security授权认证全过程

    这篇文章主要介绍了Swagger2配置Security授权认证全过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 利用Java Set 去除重复object的方法

    利用Java Set 去除重复object的方法

    下面小编就为大家带来一篇利用Java Set 去除重复object的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • Java多线程编程中线程锁与读写锁的使用示例

    Java多线程编程中线程锁与读写锁的使用示例

    这篇文章主要介绍了Java多线程编程中线程锁与读写锁的使用示例,锁是控制程序多线程并发的重要手段,需要的朋友可以参考下
    2016-04-04
  • Spring Boot 配置和使用多线程池的实现

    Spring Boot 配置和使用多线程池的实现

    这篇文章主要介绍了Spring Boot 配置和使用多线程池的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • Spring(一):IOC如何推导和理解

    Spring(一):IOC如何推导和理解

    下面小编就为大家带来一篇详谈Spring对IOC的理解(推荐篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-07-07
  • spring单例如何改多例

    spring单例如何改多例

    这篇文章主要介绍了spring单例如何改多例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01

最新评论