桶排序
桶排序
①简单介绍
桶排序如果输入数据服从均匀分布,平均情况下它的时间代价为O(n)。桶排序如果输入是由一个随机过程产生,该过程将元素均匀。独立的分布在[0,1)区间上。
②原理
桶排序将[0,1)区间划分为n个同样大小的子区间,或称为桶。然后将n个输入的数据分别放到各个桶中。由于输入数据是均匀分布的。一般不会出现非常多数落在一个桶中的情况。为了得到输出结果,先对每一个桶中的数据进行排序。再遍历每一个桶。依照次序将元素取出。如果输入的是一个包括n个元素的数组A,而且每一个元素A[i]满足0<=A[i]<1。此外,算法还须要一个暂时数组B[0..n-1]来存放链表。也就是桶,并有一种用于维护这些链表的机制。
也能够用数组来取代。
③C语言实现
#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值。
排序中用到了之前提到的高速排序算法,用来对每一个桶里面的数据进行排序,实际上将数据放入桶中的时候就已经进行了一次排序了,相当于按大类分好,再用快排排序小类。当然这里不仅限于用快排来进行辅助,选择排序什么的都能够用。