//基数排序:不是基于直接比较的排序算法(本文实现递减排序)
//每一位的取值只有10种情况,即:0-9,10是基数r
//第一趟以个位进行分配,因为是递减序列,所以收拾是从最大9开始,第一趟结束:得到按个位递减的序列
//第二趟以十位进行分配,由于第二趟的分配工作是基于第一趟,当两个十位的值相同时,按照个位递减
//第三趟以百位进行分配,若百位相同,按照十位递减,若十位还相同,按照个位递减
//要想得到递增排序,只需要先收集值更小的队列
//基数为r,关键字由d元组构成,分配O(n),收集O(r),总共d趟分配收集,时间复杂度:O(d(n+r)),空间复杂度:O(r)
//具有稳定性
#include <iostream>
#include "stdlib.h"
using namespace std;
//全局变量
int a[]={53,197,0,78,7,45,65,87,324,599,4,5,2,6};
int n=sizeof(a)/sizeof(int);
//比较元素的数据类型
typedef struct LinkNode{
int data;
struct LinkNode *next;
}LinkNode,*LinkList;
//链式队列,每个元素的数据类型是LinkNode
typedef struct{
int len;
LinkNode *front,*rear;
}LinkQueue;
//单链表的初始化(带头结点)
void initLinkList(LinkList &L){
L=(LinkNode*)malloc(sizeof(LinkNode)); //创建头结点
L->next=NULL; //头节点的后面没有节点
}
//队列初始化
void initQueue(LinkQueue a[]){
for(int i=0;i<10;i++){
a[i].front=NULL;
a[i].rear=NULL;
a[i].len=0;
}
}
//采用尾插法建立单链表
void tailInsert(LinkList &L){
LinkNode *s;
LinkNode *r=L; //r是表尾指针
for(int i=0;i<n;i++){
s=(LinkNode*)malloc(sizeof(LinkNode));
s->data=a[i];
r->next=s;
r=s; //r指向新的表尾节点
}
r->next=NULL;
}
//输出
void out(LinkList L){
LinkNode *p=L->next;
while(p!=NULL){
cout<<p->data<<" ";
p=p->next;
}
}
//除数
int chushu(int n){
int num=1;
for(int i=1;i<n;i++){
num*=10;
}
return num;
}
//每个数据是1000以下的正整数,基数r=10
void sort(LinkList &L){
LinkQueue a[10];
LinkNode *p=L->next; //p是当前处理的元素
LinkNode *q; //q是在收集数据时,指向链表L的尾部
int num; //元素备份
int wei; //元素位上的数
initQueue(a);
//总共进行三趟分配和收集
//通过改变d的上限,可以实现更大数据的排序,d最大为10
//int的取值范围为: -2^31—2^31-1,即-2147483648—2147483647
for(int d=1;d<=3;d++){
p=L->next;
while(p!=NULL){
//i==1时,wei存储的是个位;i==2时,wei存储的是十位
wei=(p->data/chushu(d))%10;
if(a[wei].len++==0){ //当前队列中没有元素
a[wei].front=p;
a[wei].rear=p;
}else{ //当前队列中起码有一个元素
a[wei].rear->next=p;
a[wei].rear=p;
}
p=p->next;
}
//清空链表,放入收集数据
L->next=NULL;
q=L;
//收集元素到链表
for(int i=9;i>=0;i--){
if(a[i].len!=0){
cout<<d<<" "<<i<<endl;
q->next=a[i].front;
q=a[i].rear;
a[i].front=NULL;
a[i].rear=NULL;
a[i].len=0;
}
}
/*不加这一句话如果数据最后一个本身是1,则正常排序
否则会陷入输出循环,目前还没想到原因 :(*/
q->next=NULL;
}
}
int main(){
LinkList L;
initLinkList(L);
tailInsert(L);
sort(L);
out(L);
return 0;
}
说明:本文为个人学习理解总结。