桶排序
桶排序(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