目前主流内排序两大类:
一类是比较关键字大小,这一类很常见,比如:
插入排序:直接插入排序(稳定)和希尔排序(升级版,不稳定);
选择排序:直接选择排序(不稳定)和堆排序(以完全二叉树为基础,不稳定);
交换排序:冒泡排序(稳定)和快速排序(升级版,不稳定);
归并排序(选择基准,稳定);
还有有一类是不必比较关键字如基数排序,它是根据关键字中各位的值通过对排序的n个元素进行分配和收集来实现排序。
思路:
设待排序的线性表中每个元素都是d位十进制正整数,在排序的过程中需要对线性表进行d趟的分配与收集,原则是比较从低(高)到高(低)的每一位,每j(j=1,2,..,d)趟过程:
1。初始化M1个链表(M1>=r);
2。关键字的第j位值aj,(0<=aj<=r-1),按照aj的值插入到编号为aj的链表中,以此n个元素都类似这样
3.做完第j趟分配以后,按照链表编号的从小到大,同一链表按照先后插入的顺序,从链表中取出所有元素构成一个新链表,既是第j趟基数排序后的结果;
4。继续下一趟。
举例:
对关键字序列{112,214,312,902,156,712,451,623,643,834}按照从低到高的基数排序:
代码:
//基数排序
//
typedef struct node{
char data[M];
node *next;
}rec;
#define M1 10
void radix_sort(rec *&p,int r,int d){
//p为待排序序列的链表指针,r为基数,d为关键字的位数
int i,j,k;
rec *head[M1],*tail[M1],*t=NULL;
for(i=d-1;i>=0;i--){
//初始化各链对
for(j=0;j<r;j++)head[j]=tail[j]=NULL;
while(p){
k=p->data[i]-'0';
if(head[k]==NULL){head[k]=p;tail[k]=p;}
else{tail[k]->next=p;tail[k]=p;}
p=p->next;
}
//进行收集
p=NULL;//初始化
for(j=0;j<r;j++)//每个链对
if(head[j]){
if(p==NULL){p=head[j];t=tail[j];}
else{t->next=head[j];t=tail[j];}
}
t->next=NULL;
}
}