1.基数排序(次位优先LSD)
首先根据基数进行建桶,比如10进制,我们就建立10个桶,{0,1,2,...,9}
以输入序列: 64, 8, 216, 512, 27, 729, 0, 1, 343, 125为例
第一轮根据个位数的值,分别放入相应的桶中:
进行完这一轮之后,我们根据放入桶中的顺序,用链表串起来,进行第二轮,根据十位数放入相应位置:
然后根据放入桶中的顺序,再次用链表串起来,在它上面进行第三轮:根据百位数:
然后我们再用链表按顺序串起来,我们发现已经有序了,为了保险,我们可以再进行一轮,然后遍历链表,将值放回数组就可以。
#define Maxsize 1000
#define Radix 10
#define MaxDigit 4
typedef struct Node *ptrnode;
struct Node
{
int key;
ptrnode next;
};
struct NodeBucket
{
ptrnode head,tail;
};
typedef struct NodeBucket Bucket[Maxsize];
int getnum(int x,int d)
{
int i,y;
for(i=1;i<=d;i++)
{
y=x%Radix;//取一位数
x=x/Radix;
}
return y;
}
void LSD(int a[],int n)
{
ptrnode head,tmp,p;
head=NULL;
Bucket B;
int i;
for(i=0;i<n;i++)//从头插入元素
{
tmp=(ptrnode)malloc(sizeof(struct Node));
tmp->next=head;
tmp->key=a[i];
head=tmp;
}
//设立10个桶{0,1,2,3,4,..9} 假设最大有4位数
int D,Di,ans;
for(D=1;D<=MaxDigit;D++)
{
p=head;//记录所有元素的链表
while(p!=NULL)
{
tmp=p;
Di=getnum(tmp->key,D);//取出一位数
p=p->next;//从链表中删除tmp
tmp->next=NULL;
//将元素放入相应的桶中
if(B[Di].head==NULL)
{
B[Di].head=B[Di].tail=tmp;
}
else
{
B[Di].tail->next=tmp;
B[Di].tail=tmp;//tail指向末尾
}
}
//第一轮将元素放入桶中之后进行元素的收集,也就是用一个链表串起来
//由于采取的是头插法 所以我们倒着来插入
head=NULL;
for(Di=Radix-1;Di>=0;Di--)
{
if(B[Di].head!=NULL)
{
B[Di].tail->next=head;
head=B[Di].head;
B[Di].head=B[Di].tail=NULL;//清空这个桶
}
}
//现在head里存放的是按照第一轮排序顺序存放的数值,进行新一轮排序
}
//排序结束,把所有值放回数组
for(i=0;i<n;i++)
{
tmp=head;
a[i]=tmp->key;
head=head->next;
free(tmp);
}
}