简单桶排序(Bucket Sort)

1.基本思想

桶排序是将待排序集合中处于同一个值域的元素存放在同一个桶中1

2.算法设计2

假设有一个班级有5个人,这次期末他们分别考了5分,2分,4分,5分,8分(满分为10分)。需要将这些分数从小到大排序

首先我们申请一个大小为11的数组int bucket[11]。在最开始的时候我们都把该数组的元素bucket[0]~bucket[10]都初始化为0,表示这些分数都还没有人得到过。例如bucket[0]表示的是目前还没有人得到0分,bucket[8]表示的是目前还没有人得到8分。
初始化

  1. 开始处理每一个分数。第一个人的分数为5分,那么就将bucket[5]的值在原来的基础上加1,即bucket[5]的值从0变为1,表示5分出现过一次
    1
  2. 第二个人的分数为2分,那么就将bucket[2]的值在原来的基础上加1,即bucket[2]的值从0变为1,表示2分出现过一次
    2
  3. 第三个人的分数为4分,以此类推,可得
    3
  4. 第四个人的分数为5分,注意了,我们在bucket[5]的值在原来的基础上加1,那么bucket[5]的值从1变为2,表示5分出现两次
    4
  5. 最后一个人的分数为8分,得
    5
    最终,只需要将出现过的分数打印出来

3.代码

public class SimpleBucketSort {
	public static void main(String[] args) {
		// 下面是学生取得的分数,假设分数最大为10
		int[] a = {5,3,5,2,8};
		// 创建11个分数层,a[0]=0:表示分数为0分的出现0个人
		int[] bucket = new int[11];
		for(int i = 0; i < a.length; i++) {
			// 出现分数为a[i]的有barrel[a[i]]个人
			bucket[a[i]]++;
		}
		// 打印
		for (int i = 0; i < bucket.length; i++) {
			// 出现几次就打印几次
			for(int j = 1; j <= bucket[i]; j++) {
				System.out.print(i + " ");
			}
		}
	}
}

4.复杂度

  • 时间复杂度

在初始化桶时,需要循环n次(n为桶的个数,在java语言中默认都已经初始化为0),在把分数放入桶中时,循环了m次(m为待排序的个数),而在打印时一共循环了(m+n)次,所以整个排序算法一共执行了(n+m+m+n)次。用大写的O来表示时间复杂度,因此该算法的时间复杂度为O(n+m+m+n),即O(2(n+m))。但是一般在说时间复杂度时都是忽略常数,也就是桶排序的最终时间复杂度为O(m+n),并且一般字母都得大写表示,即O(M+N)。

  • 空间复杂度

桶排序所占用的空间比较糟糕,非常浪费空间,如果要排序的数的范围在0~10000000000000,那得创建出10000000000001个变量。创建N个桶,并且待排序的数为M,那么空间复杂度为O(N+M)。

5.优缺点

  • 优点

速度是比较快的,从上面的时间复杂度可以看出。

  • 缺点

比较浪费空间,假设待排序的数中有一个元素值为2100000000000,那么必须创建一个大于2100000000000的桶数。

6.思考

  • 该算法其实可以来做去重复元素,只需要在打印时做一点改动。
// 打印(去重)
for(int i = 0; i < barrel.length; i++) {
	if(barrel[i] != 0) {
		// 打印的是分数
		System.out.print(i + " ");
	}
}
  • 目前使用桶排序来对分数进行排序,那么目前要是姓名和分数,要求将名字按分数从小到大排序后打印输出,目前的简单桶排序做不到,输出的只能是分数。

  1. 参考博客:https://www.jianshu.com/p/204ed43aec0c ↩︎

  2. 参考书籍:《啊哈!算法》 ↩︎

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值