排序算法-桶排序

桶排序

桶排序(Bucket Sort)的原理很简单,它是将数组分到有限数量的桶子里。

假设待排序的数组data中共有N个整数,并且已知数组data中数据的范围[0, MAX)。在桶排序时,创建容量为MAX的桶数组buckets,并将桶数组元素都初始化为0;将容量为MAX的桶数组中的每一个单元都看作一个"桶"。在排序时,逐个遍历数组data,将数组data的值,作为"桶数组buckets"的下标。当data中数据被读取时,就将桶的值·加1·。

例如,读取到数组data[3]=5,则将buckets[5]的值+1。

在将数据放到桶中之后,再通过一定的算法,将桶中的数据提出出来并转换成有序数组。就得到我们想要的结果了。
在这里插入图片描述

代码实现:

/*

桶排序(Bucket Sort)的原理很简单,它是将数组分到有限数量的桶子里。

假设待排序的数组data中共有N个整数,并且已知数组data中数据的范围[0, MAX)。
在桶排序时,创建容量为MAX的桶数组buckets,并将桶数组元素都初始化为0;
将容量为MAX的桶数组中的每一个单元都看作一个"桶"。
在排序时,逐个遍历数组data,将数组data的值,作为"桶数组buckets"的下标。
当data中数据被读取时,就将桶的值加1。
例如,读取到数组data[3]=5,则将buckets[5]的值+1。

参数说明:
    data -- 待排序数组
    n -- 数组data的长度
    max -- 数组data中最大值的范围
    
*/
 
#include <stdio.h>
#include <string.h>

void bucket_sort(int data[], int n, int max)
{
    int i,j;
    int buckets[max];

    // 将buckets中的所有数据都初始化为0。
    memset(buckets, 0, max*sizeof(int));

    // 1. 把数组放入对应桶中 
    for(i = 0; i < n; i++) 
        buckets[data[i]]++; 

    // 2. 排序data数组 
    for (i = 0, j = 0; i < max; i++) 
    {
    	//一个桶中可能包含了data中的多个数据 
    	//如果data中有相同的数据依次存放在后面 
        while( (buckets[i]--) >0 )
            data[j++] = i;
    }
}
int main()
{
    int data[] = {8,3,6,2,4,5,7,1,9,0};
    
    printf("排序前的数据为:\n");
    for(int i=0; i<10;i++)
        printf("%d  ",data[i]);
    printf("\n\n");
    
    bucket_sort(data,10,10);
    
    printf("排序后的结果为:\n");
    for(int i=0; i<10;i++)
        printf("%d  ",data[i]);
    printf("\n");
    
    return 0;
}

运行结果:

在这里插入图片描述

算法分析:

因为将n个数据平均分配到m个桶里,每个桶里面的元素有k=n/m个,所以桶内排序使用快排时间复杂度为O(k*log2k), m个桶时间复杂度为O(m*k*log2k),因为k=n/m,所以整个桶排序时间复杂度为O(nlog2(n/m)),当m接近n时log2(n/m)是一个非常小的数,所以桶排序时间复杂度为O(n).

常见使用场景:

  • 数据很容易被分到m个桶,且桶之间存在大小关系.
  • 数据在各个桶之间分布均匀.
排序方法时间复杂度(平均)时间复杂度(最坏)时间复杂度(最好)空间复杂度稳定性
桶排序O(n)O(nlog2n)O(n)O(m)稳定

参考链接:
https://www.jianshu.com/p/d28cbf592ae8
https://www.cnblogs.com/skywang12345/p/3602737.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值