1.理论
桶排序的基本思想
假设有一组长度为N的待排关键字序列K[1....n]。首先将这个序列划分成M个的子区间(桶) 。然后基于某种映射函数 ,将待排序列的关键字k映射到第i个桶中(即桶数组B的下标 i) ,那么该关键字k就作为B[i]中的元素(每个桶B[i]都是一组大小为N/M的序列)。接着对每个桶B[i]中的所有元素进行比较排序(可以使用快排)。然后依次枚举输出B[0]....B[M]中的全部内容即是一个有序序列。
桶—关键字映射函数
bindex=f(key) 其中,bindex 为桶数组B的下标(即第bindex个桶), k为待排序列的关键字。桶排序之所以能够高效,其关键在于这个映射函数,它必须做到:如果关键字k1<k2,那么f(k1)<=f(k2)。也就是说B(i)中的最小数据都要大于B(i-1)中最大数据。很显然,映射函数的确定与数据本身的特点有很大的关系,我们下面举个例子:
假如待排序列K= {49、 38 、 35、 97 、 76、 73 、 27、 49 }。这些数据全部在1—100之间。因此我们定制10个桶,然后确定映射函数f(k)=k/10。则第一个关键字49将定位到第4个桶中(49/10=4)。依次将所有关键字全部堆入桶中,并在每个非空的桶中进行快速排序后得到如下图所示:
对上图只要顺序输出每个B[i]中的数据就可以得到有序序列了。
2.C代码
/*************************************************************************
> File Name: bucketSort.c
> Author: NULL
> Mail: 574889524@qq.com
> Created Time: 2014年11月02日 星期日 00时11分40秒
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#define ARRSIZE 8
struct node{
int iKey;
struct node *pNext;
};
/**********************************************/
void print(int *A,int length)
{
int i;
for(i=0;i<length;++i)
printf("%d ",A[i]);
printf("\n");
}
/**********************************************/
void BucketSort(int *pArr,int iLenght,int iBucketSize)
{
int i,j,index;
struct node **pBucketTable = (struct node**)malloc(iBucketSize*sizeof(struct node));
for(i=0;i<iBucketSize;++i){/*初始化桶*/
pBucketTable[i]=(struct node*)malloc(sizeof(struct node));
pBucketTable[i]->iKey = 0;/*记录每一个桶中的元素个数*/
pBucketTable[i]->pNext = NULL;
}
for(i=0;i<iLenght;++i){
struct node *pNode = (struct node *)malloc(sizeof(struct node));
pNode->iKey = pArr[i];
pNode->pNext = NULL;
index = pArr[i]/10;/*计算桶号*/
struct node *pHead = pBucketTable[index];/*初始化pHead为桶中数据链表的头指针*/
if(0 == pHead->iKey){/*说明桶中没有数据*/
pBucketTable[index]->pNext = pNode;
(pBucketTable[index]->iKey)++;
}else{/*将数据插入到链表结构中*/
while(pHead->pNext!=NULL && pHead->pNext->iKey <= pNode->iKey)
pHead = pHead->pNext;
pNode->pNext = pHead->pNext;
pHead->pNext = pNode;
(pBucketTable[index]->iKey)++;
}
}
/*将结果返回*/
i = 0;
struct node *p,*q;
for(j = 0;j<iBucketSize;j++)
for(p=pBucketTable[j]->pNext;p!=NULL;p=p->pNext){
pArr[i++] = p->iKey;
}
/*释放内存*/
for(j = 0;j<iBucketSize;j++){
p=pBucketTable[j]->pNext;
while(p!=NULL){
q= p->pNext;
free(p);
p = q;
}
j++;
}
free(pBucketTable);
}
/**********************************************/
int main()
{
int Arr[ARRSIZE]={49,38,65,97,76,13,27,49};
BucketSort(Arr,ARRSIZE,10);
print(Arr,ARRSIZE);
return 0;
}