二十二、自己动手实现排序算法(10)------“ Bucket Sort 桶排序 ”

桶排序是一种计数排序的升级版,适用于输入数据服从均匀分布的情况。它通过映射函数将数据分配到有限数量的桶中,然后对每个桶进行排序。桶排序算法描述包括设置桶大小、遍历数据并放入对应桶、对非空桶排序,最后将排序好的数据合并。Java代码实现展示了算法的具体步骤,适合理解桶排序的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考文章:

https://www.cnblogs.com/guoyaohua/p/8600214.html                  十大经典排序算法最强总结(含JAVA代码实现)

https://mp.weixin.qq.com/s/qrboxA5SwN7AbAcpZ_dpNQ             漫画:什么是桶排序?

https://www.runoob.com/w3cnote/bucket-sort.html                        1.9 桶排序

https://github.com/hustcc/JS-Sorting-Algorithm/blob/master/9.bucketSort.md     桶排序


桶排序分析:

平均时间复杂度最好情况最坏情况空间复杂度排序方式稳定性
O(n+k)O(n+k)O(n^2)O(k)Out-place稳定

温馨提示:

        如果代码看不懂,那就拿出纸和笔,照着代码流程走一遍,走一遍,再走一遍,另外看基数排序,最好先把其他的排序都给看了,再看这个会好理解一些。

 

桶排序原理:

       桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。

       桶排序 (Bucket sort)的工作的原理: 假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序。

 

算法描述:

  • 人为设置一个BucketSize,作为每个桶所能放置多少个不同数值(例如当BucketSize==5时,该桶可以存放{1,2,3,4,5}这几种数字,但是容量不限,即可以存放100个3);
  • 遍历输入数据,并且把数据一个一个放到对应的桶里去;
  • 对每个不是空的桶进行排序,可以使用其它排序方法,也可以递归使用桶排序;
  • 从不是空的桶里把排好序的数据拼接起来。 

注意,如果递归使用桶排序为各个桶排序,则当桶数量为1时要手动减小BucketSize增加下一循环桶的数量,否则会陷入死循环,导致内存溢出。

 

桶排序图解:

 

Java 代码实现:

代码一:


package com.sorting.algorithm;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class BucketSort {
	
	public static int[] bucketSort(int[] array ){
		
		// 1,计算最大最小值,划分桶区间
		int max = array[0], min = array[0];
		for (int i = 0; i < array.length; i++) {
			if(max < array[i])
				max = array[i];
			if(min > array[i])
				min = array[i];
		}
		
		// 创建len个桶,桶内装入的元素用 arraylist 存储,每个桶的大小最多为len个元素
		int bucketNum = 10;
		int len = (max - min)/bucketNum + 1;
		ArrayList<ArrayList<Integer>> buckets = new ArrayList<>(len);
		// 对桶进行初始化
		for (int i = 0; i < len; i++) {
			buckets.add(new ArrayList<Integer>());
		}
		
		// 2, 将数组中的数据放入桶中,并进行排序
		for (int i = array.length-1; i >= 0; i--) {
			int index =(int) Math.floor((array[i] -min)/bucketNum);
			buckets.get(index).add(array[i]);
		}
		
		// 将桶中数据进行排序
		for (int i = 0; i < buckets.size(); i++) {
			Collections.sort(buckets.get(i));
			System.out.println(buckets.get(i));
		}
		
		// 3, 将桶中排序好的数据拿出,放到数组中
		int index=0;
		int[] sortedArr = new int[array.length];
		for (int i = 0; i < buckets.size(); i++) {
			for (int j = 0; j < buckets.get(i).size(); j++) {
				sortedArr[index++] = buckets.get(i).get(j);
			}
		}
		
		return sortedArr;
	}
	
	public static void printArr(int[] array){
		for (int i = 0; i < array.length; i++) {
			if(i != array.length-1)
				System.out.print(array[i]+ ", ");
			else
				System.out.println(array[i]);
		}
		System.out.println();
	}
	
	public static void printArr(List<Integer> array){
		for (int i = 0; i < array.size(); i++) {
			if(i != array.size()-1)
				System.out.print(array.get(i)+ ", ");
			else
				System.out.println(array.get(i));
		}
		System.out.println();
	}
	
	public static void main(String[] args) {
		
		int[] array = {3,14,28,56,27,66,33,21,21,22,23,43,37,33,31};
		
		System.out.println("排序之前:");
		
		printArr(array);
		int[] sortedArr = bucketSort(array);

		System.out.println("排序之后:");
		printArr(sortedArr);
	}
}

 

 

 

 

桶排序代码测试:

代码一:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值