当桶排序(bucket sort)的输入符合均匀分布时,即可以以线性期望时间运行。具体来说,计数排序假设输入是由一个小范围内的整数构成,而桶排序则假设输入由一个随机过程产生,该过程将元素均匀而独立地分布在区间[0,1)上。
排序思想
桶排序的思想即把区间[0,1)划分成n个大小相同的的子区间,或称桶。然后将n个输入数分布到各个桶中去。为得到结果,对各个桶中的数进行排序,然后按次序把各个桶中的元素列出来即可。
BUCKET-SORT(A)
n <- length[A]
for i <- 1 to n
do insert A[i] into list B[n*A[i]]
for i <- 0 to n-1
do sort list B[i] with insertion sort
concatenate the lists B[0],B[1],B[n-1] together in order
实现中用到了基于链表的插入排序(主要思想将无序链表逐渐插入一个有序链表中,实现中每个链表都带有一个单独的链表头结点):
typedef struct node* link;
typedef struct node
{
float item;
link next;
};
link insertSort(link heada)
{
link t,u,x,a=heada,b;
link headb = (link)malloc(sizeof node);
b = headb;
b->next = NULL;
for (t=a->next;t!=NULL;t=u)
{
u = t->next;
for (x=b;x->next!=NULL;x=x->next)
if (x->next->item > t->item)
break;
t->next = x->next;
x->next = t;
}
return headb;
}
link bucketSort(float list[],int len)
{
link *B = (link*)malloc(sizeof(link)*len);
int i;
link temp,lnew;
/* init len buckets */
for (i=0;i<len;i++)
{
B[i] = (link)malloc(sizeof node);
B[i]->next = NULL;
}
/* insert into buckets */
for (i=0;i<len;i++)
{
temp = (link)malloc(sizeof node);
temp->item = list[i];
temp->next = NULL;
lnew = B[(int)(len*list[i])];
while(lnew->next)
lnew = lnew->next;
lnew->next = temp;
}
/* insert sort in every bucket */
for(i=0;i<len;i++)
{
temp = B[i];
if(temp->next)
B[i] = insertSort(temp);
}
/* concatenate the buckets together in order */
link R = (link)malloc(sizeof node);
lnew = R;
for(i=0;i<len;i++)
{
temp = B[i]->next;
while(temp)
{
lnew->next = temp;
temp = temp->next;
lnew = lnew->next;
}
}
/* over ,return R */
return R;
}
测试数据及结果输出:
0.41 0.67 0.34 0.00 0.69 0.24 0.78 0.58 0.62 0.64
0.00 0.24 0.34 0.41 0.58 0.62 0.64 0.67 0.69 0.78
参考资料:
http://bbs.chinaunix.net/thread-932775-1-1.html
算法导论 第八章 线性时间排序