基数排序是一种不需要比较就能实现排序的算法思维,主要步骤为分配和收集的过程,重复这个过程于最大数的位数后,排序结束。
以下是完全以队列模拟桶的分配收集过程。
头文件(单链表部分): typedef int ElemType; typedef struct LNode { ElemType data; struct LNode *next; }LNode,*LinkList; int InitList_link(LinkList *head) //初始化函数 { *head=(LinkList)malloc(sizeof(LNode)); //产生头结点 if(NULL==*head) return -1; //初始化失败 (*head)->next=NULL; return 0; //初始化成功 } int ListEmpty_link(LinkList head) //判空函数 { if(NULL==head->next) return 1; //单链表为空 return 0; //单链表不为空 } int ListLength_link(LinkList head) //求长度函数 { int len=0; LNode *p=head->next; while(NULL!=p) { len++; p=p->next; } return len; } int ListGet_link(LinkList head, int i, ElemType *x) //取单链表中的某一个元素 { LNode *p; int j; p=head; j=-1; while(p->next!=NULL&&j<i) //查找返回 { p=p->next; j++; } if(j!=i) { printf("取元素位置参数错"); return 0; } *x=p->data; return 1; } int ListInsert_link(LinkList head,int i,ElemType e) //在任意位置进行插入 { int count=0; LNode *p=head,*q=NULL; while(count<i-1&&NULL!=p) { p=p->next; count++; } if(count>i-1||NULL==p) return -1; q=(LNode *)malloc(sizeof(LNode)); if(NULL==q) return -2; q->data=e; q->next=p->next; p->next=q; return 0; } 头文件(队列)部分: #define MAX 100 typedef enum{Empty,Full} StateType; typedef struct { ElemType data[MAX]; int front,rear; StateType tag; }CSqQueue; int InitQueue_csq(CSqQueue *Q) //顺序循环队列---课本代码 { (*Q).front=0; (*Q).rear=0; (*Q).tag=Empty; return 0; } int QueueEmpty_csq(CSqQueue Q) { if(Q.front==Q.rear&&Empty==Q.tag) return 1; return 0; } int QueueFull_csq(CSqQueue Q) { if(Q.front==Q.rear&&Full==Q.tag) return 1; return 0; } int QueueLength_csq(CSqQueue Q) { if(QueueEmpty_csq(Q)) return 0; else if(QueueFull_csq(Q)) return MAX; return (Q.rear-Q.front+MAX)%MAX; } int EnQueue_csq(CSqQueue *Q,ElemType e) { if(QueueFull_csq(*Q)) return -1; (*Q).data[(*Q).rear]=e; (*Q).rear=((*Q).rear+1)%MAX; (*Q).tag=Full; return 0; } int DeQueue_csq(CSqQueue *Q,ElemType *e) { if(QueueEmpty_csq(*Q)) return -1; *e=(*Q).data[(*Q).front]; (*Q).front=((*Q).front+1)%MAX; (*Q).tag=Empty; return 0; } 头文件(桶排)部分: typedef int KeyType; ElemType MaxList_link(LinkList head) { ElemType e; ElemType a[MAX]; int i; for(i=0;i<ListLength_link(head);i++) { //假设输入为3\1\2 ListGet_link(head,i,&a[i]); //依次取元素3、1、2 } e=a[0]; for(i=1;i<ListLength_link(head);i++) { if(e<a[i]) e=a[i]; //e取最大值 } return e; } int Num(ElemType e) { int i=0; while(e) { e/=10; i++; } return i; } void RadixSort(LinkList *head,KeyType key) { CSqQueue q[10]; //10个队列模拟桶操作过程 ElemType x; int i,j,k; ElemType tag; for(i=0;i<10;i++) InitQueue_csq(&q[i]); //初始化10桶 for(i=0;i<ListLength_link(*head);i++) //待排的个数 { ListGet_link(*head,i,&x); //顺序取单链表元素 tag=x; j=key; //n位数 //这里应该用LSD,而不是MSD j--; while(j--) //没有高位补0操作 { tag/=10; } switch(tag%10) //入相应的桶 { case 0: EnQueue_csq(&q[0],x); break; case 1: EnQueue_csq(&q[1],x); break; case 2: EnQueue_csq(&q[2],x); break; case 3: EnQueue_csq(&q[3],x); break; case 4: EnQueue_csq(&q[4],x); break; case 5: EnQueue_csq(&q[5],x); break; case 6: EnQueue_csq(&q[6],x); break; case 7: EnQueue_csq(&q[7],x); break; case 8: EnQueue_csq(&q[8],x); break; default: EnQueue_csq(&q[9],x); break; } } k=1; InitList_link(head); for(i=0;i<10;i++) //10个桶收集过程 { for(j=0;j<QueueLength_csq(q[i]);) //这里有个陷阱 { DeQueue_csq(&q[i],&x); ListInsert_link(*head,k,x); k++; } } } 源文件部分: #include<stdio.h> #include<stdlib.h> #include"LinkList.h" #include"Queue.h" #include"RadixSort.h" int main() { LinkList list; int i,x; KeyType key; InitList_link(&list); printf("请输入一组无序的数据以负数结束:"); i=1; while(scanf("%d",&x)&&x>0) { ListInsert_link(list,i,x); //入表 i++; } key=Num(MaxList_link(list)); //获得最大数的位数以确定分配收集的次数 int flag=1; for(i=1;flag<=key;i++) { RadixSort(&list,flag); flag++; } printf("基数排序后,该组数据依次为:"); for(i=0;i<ListLength_link(list);i++) { ListGet_link(list,i,&x); printf("%d ",x); } return 0; } 以上代码可以实现基数排序,但是待排的序列中不能含有0,具体没来得及看,嘿嘿~
原文地址:http://blog.csdn.net/huangqiang1363/article/details/41983983