热门课程

免费试听

上课方式

开班时间

当前位置: 首页 -   文章 -   新闻动态 -   正文

Java经典算法——桶排序

知了堂姐
2024-07-09 11:12:24
0

1、什么是桶排序?

桶排序是一种稳定的排序算法。它的工作原理是将序列中的元素分布到一定数量的桶内,然后分别对每个桶内的元素进行排序,最后再将各个桶内的有序子序列放回原始序列中。对于单个桶内的元素排序,我们可以使用别的排序算法,也可以递归使用桶排序。一般来说,对于单个桶内的元素,使用插入排序算法对它们进行排序。

2、问题

假设目前有包含 100,200,300,400,500,600 共 6 个数字的一个随机顺序的集合。我们需要对这个集合进行桶排序。

3、分析桶排序

桶排序需要思考两个问题,有多少个桶?每个桶多大也就是每个桶放多少?

首先我们设置桶的大小为 2 。

然后一共有6个数字,除以每个桶的大小,就是需要多少个桶,在这里我们需要3个桶。

现在有桶了,我们需要一个方法找到元素对应的桶。我们使用一个计算公式来计算所属哪个桶:f(x) = (int)((x - min) / (max - min + 1.0) * 桶个数)。

(x - min) / (max - min + 1.0) 计算出的结果 是一个大于等于0,最大趋近于1且不等于1的值,然后乘以桶的个数进行强转整数类型,就可以计算出0-9之间的一个数字,就代表具体的桶编号。之所以用这个公式,是因为这个公式会随着 x 的变大而变大,可以保证桶内数据是在某个范围内,且后边的桶比前边的桶内存放的数据要大。

每个桶都存放完成后,遍历10个桶,每个桶都进行插入排序。排序完一个桶后就将这个桶中的数据放回原先的集合中。

4、步骤

  1. 设置几个数组作为空桶。
  2. 从左到右遍历待排序序列,把每个元素都放到对应的桶中
  3. 对每个不是空的桶进行排序
  4. 依次取出所有桶中的元素放回原序列

5、根据《算法》中描述每个桶的大小在 5~10 之间性能最优。

时间空间复杂度分析:

空间复杂度:因为排序过程中用到了一个辅助桶来存储元素,所以空间复杂度是O(n)

时间复杂度:有 n 个待排序元素,均匀地将这些元素划分到 bucketCount 个桶内,每个桶里就有 k=n/bucketCount 个元素。每个桶内部使用快速排序,时间复杂度为 O(k logk)。m 个桶排序的时间复杂度就是 O(bucketCount k logk),因为 k=n/bucketCount,所以整个桶排序的时间复杂度就是 O(nlog(n/bucketCount))。当桶的个数 bucketCount 接近数据个数 n 时,log(n/bucketCount) 就是一个非常小的常量,这个时候桶排序的时间复杂度接近 O(n)。所以时间复杂度为O(n)

桶排序的适应场景

桶排序对数据要求较高,适用于数据是均匀分布的情况,这样可以让分布到各个桶内的元素数量相当。而不是被集中分配到其中一个桶或几个桶。

比较适合用在外部排序中。

因为数据量比较大,数据存储在外部磁盘中,无法一次性全部放入内存进行排序,一部分一部分的读入内存再写入磁盘,这种方式称为外部排序。

代码实现

Java实现代码

public class BucketSort {
    private void insertionSort(List arr) {
      if (arr == null || arr.size() == 0) return;
      for (int i = 1; i < arr.size(); ++i) {
        int cur = arr.get(i);
        int j = i - 1;
        while (j >= 0 && arr.get(j) > cur) {
          arr.set(j+1, arr.get(j));
          --j;
        }
        arr.set(j+1, cur);
      }
    }
    private int bucketSize;
    public BucketSort(int bucketSize) {
      this.bucketSize = bucketSize;
    }
    public void sort(int[] arr) {
      if (arr == null || arr.length == 0) return;
      int max = arr[0], min = arr[0];
      for (int num: arr) {
        if (num > max) max = num;
        if (num < min) min = num;
      }
      int bucketCount = arr.length / bucketSize;
      List> buckets = new ArrayList<>(bucketCount);
      for (int i = 0; i < bucketCount; ++i)
        buckets.add(new ArrayList<>());
      for (int num: arr) {
        int idx = (int)((num - min) / (max - min + 1.0) * bucketCount);
        buckets.get(idx).add(num);
      }
      int idx = 0;
      for (List bucket: buckets) {
        insertionSort(bucket);
        for (int num: bucket)
          arr[idx++] = num;
      }
    }
 }

JavaScript实现代码

def Bucket_Sort(array, bucketsize):
    minValue = min(array)
    maxValue = max(array)
    res = []
    bucketcount = (maxValue - minValue + 1) // bucketsize
    bucket_lists = [[] for i in range(bucketcount)]
    
    for i in array:
        bucket_index = (i - minValue) // bucketsize
        bucket_lists[bucket_index].append(i)
    # 桶内排序
    for j in bucket_lists:
        Quick_Sort_2(j, 0, len(j)-1)    

    for j in bucket_lists:
        if len(j) != 0:
            res.extend(j)
    return res

进阶之路

查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中。因为其实现代码较短,应用较常见。所以在面试中经常会问到排序算法及其相关的问题。但万变不离其宗,只要熟悉了思想,灵活运用也不是难事。

一般在面试中最常考的是快速排序归并排序,并且经常有面试官要求现场写出这两种排序的代码。对这两种排序的代码一定要信手拈来才行。还有插入排序、冒泡排序、堆排序、基数排序、桶排序等。

面试官对于这些排序可能会要求比较各自的优劣、各种算法的思想及其使用场景。还有要会分析算法的时间和空间复杂度。通常查找和排序算法的考察是面试的开始,如果这些问题回答不好,估计面试官都没有继续面试下去的兴趣了。

所以想开个好头,就要把常见的排序算法思想及其特点熟练掌握,有必要时能熟练写出代码。


 

大家都在看

知了堂杨总受邀到成农院开展《大数据、人工智能时代...

2024-07-09 浏览次数:0

Java都25岁了,她还好吗?

2024-07-09 浏览次数:0

网络安全必备:网安必考证书,你get了吗?

2024-07-09 浏览次数:0

知了汇智实训课程及系列讲座,走进川信职院、吉利学...

2024-07-09 浏览次数:0

前端人才饱和了吗?现在学前端还好找工作吗?

2024-07-09 浏览次数:0

owasp十大web漏洞:owasp top 1...

2024-07-09 浏览次数:0
最新资讯
Java工程师薪资待遇怎么样—...   Java工程师薪资待遇怎么样?Java编程的薪水还是很不错的,如果有不懂的话,我们可以通过很多途...
学习Java需要什么条件?学J...   想学习Java但又不知从何学起,0基础不知道怎么开始学习,不需要任何基础的学习Java,零的基础...
现在从事Java开发的发展前景...   电脑的诞生和广泛应用,促进了IT领域的发展,但是21世纪的计算机早已不再是进入INTERNET的...
什么是Java工程师?Java...   什么是Java工程师?  Java应用可谓无所不在,从桌面办公应用到网络数据库等应用,从PC到嵌...
java培训完找不到工作怎么班...   参加Java培训是很多转行Java的首选,但是有很多人都会有现象,Java培训完找不到工作,怎么...
java基础要学多久?小白学J...   Java的学习是基础是非常重要的一环,学好基础才能走的更稳走的更远。你知道Java基础要学多久吗...
鸿蒙OS是Java还是C语言?...   随着鸿蒙操作系统的逐渐普及,越来越多的开发者和科技爱好者开始关注其背后的技术细节。其中,一个备受...
web前端开发和java开发哪...   IT行业在国内的发展形势已经是非常不错了,程序员比比皆是,那么尾巴前端开发和Java开发哪个好?...