桶排序假设输入数据服从均匀分布,平均情况下它的时间代价为O(n)。桶排序假设输入是由一个随机过程产生,该过程将元素均匀,独立的分布在[0,1)区间上。
桶排序将[0,1)区间划分为n个相同大小的子区间,或称为桶。然后将n个输入的数据分别放到各个桶中。因为输入数据是均匀分布的,一般不会出现很多数落在一个桶中的情况。为了得到输出结果,先对每个桶中的数据进行排序,再遍历每个桶,按照次序将元素取出。假设输入的是一个包含n个元素的数组A,并且每个元素A[i]满足0<=A[i]<1。此外,算法还需要一个临时数组B[0..n-1]来存放链表,也就是桶,并有一种用于维护这些链表的机制。也可以用数组来代替。
#define BUCKET_NUM 10
#define BUCKET_SIZE 10
//快速排序,用来对每个桶中的数据进行排序
int partition(int* a, int start, int end)
{
int x = a[end];
int i = start;
//调整整个数组中元素的位置并找出中间值的索引
for (int j = start; j < end; j++)
{
if (a[j] <= x)
{
int t = a[i];
a[i] = a[j];
a[j] = t;
i++;
}
}
//将中间值放在找出的中间值索引处
int t = a[i];
a[i] = a[end];
a[end] = t;
return i;
}
//快速排序,用来对每个桶中的数据进行排序
void quick_sort(int* a, int from, int to)
{
if (from < to)
{
int p = partition(a, from, to);
quick_sort(a, from, p - 1);
quick_sort(a, p + 1, to);
}
}
//得到每个桶的当前索引
int get_bucket_index(int sub_bucket[])
{
int index = 0;
while (-1 != sub_bucket[index])
index++;
return index;
}
//将每个桶中数据挨个排序
void sort_sub_bucket(int bucket[BUCKET_NUM][BUCKET_SIZE])
{
for (int i = 0; i < BUCKET_NUM; i++)
{
int to = get_bucket_index(bucket[i]);
//对每个桶进行快速排序
quick_sort(bucket[i],0,to - 1);
}
}
//从桶中获取数据
void get_num(int* a, int bucket[BUCKET_NUM][BUCKET_SIZE])
{
int array_index = 0;
for (int i = 0; i < BUCKET_NUM; i++)
{
int to = get_bucket_index(bucket[i]);
for (int j = 0; j < to; j++)
{
a[array_index++] = bucket[i][j];
}
}
}
void bucket_sort(int* a , int count)
{
int bucket[BUCKET_NUM][BUCKET_SIZE];
//初始化桶的数据
for (int i = 0; i < BUCKET_NUM; i++)
for (int j = 0; j < BUCKET_SIZE; j++)
bucket[i][j] = -1;
//将数据挨个放入桶中
for (int i = 0; i < count; i++)
{
int digit = a[i] / 10;
int bucket_index = get_bucket_index(bucket[digit]);
bucket[digit][bucket_index] = a[i];
}
//将每个桶中的数据排个序
sort_sub_bucket(bucket);
//从桶中取出数据
get_num(a,bucket);
}
void main()
{
int count, *p;
printf("请输入需要排序的数的个数 :");
scanf_s("%d", &count);
p = (int*)malloc(count * sizeof(int));
printf("\n请输入需要排序的%d个数字:",count);
for (int i = 0; i < count; i++)
{
scanf_s("%d", p+i);
}
printf("\n快速排序后的数组:");
bucket_sort(p,count);
for (int i = 0; i < count; i++)
{
printf("%d ", p[i]);
}
printf("\n");
system("pause");
}
在上面的桶排序中,一共有10个桶,每个桶的大小为10,因此只能比较100以内的数的大小,可以根据自己需要的范围来调整前面的define值。排序中用到了之前提到的快速排序算法,用来对每个桶里面的数据进行排序,实际上将数据放入桶中的时候就已经进行了一次排序了,相当于按大类分好,再用快排排序小类。当然这里不仅限于用快排来进行辅助,选择排序什么的都可以用。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/jing_unique_da/article/details/46706005