#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define maxspace 100
#define keylen 10
#define radix_n 10
#define radix_c 26
typedef char keytype;
typedef struct{
char start[10]; //起点
char end[10]; //终点
char sche[10]; //班期
char time1[10]; //起飞时间
char time2[10]; //到达时间
char model[10]; //机型
int price; //票价
}infotype; //航班记录类型
typedef struct{
keytype keys[keylen]; //关键字(航班号)
infotype others;
int next;
}slnode; //静态链表接点类型
typedef struct{
slnode sl[maxspace]; //静态链表,sl[0]为头结点
int keynum; //记录当前关键字字符个数
int length; //当前表长
}sllist; //静态链表类型
void distribute(slnode *sl,int i,int *f,int *e)
{
int j,p;
for(j=0;j<radix_n;j++)
{//各子表置为空表
f[j]=0;
e[j]=0;
}
for(p=sl[0].next;p;p=sl[p].next)
{
j=sl[p].keys[i]%48; //将数字字符转换成相对应的数值型数字
if(!f[j])
f[j]=p;
else
sl[e[j]].next=p;
e[j]=p; //将p指向的结点插入到第j个子表中
}
}
//一趟数字字符的收集函数
void collect(slnode *sl,int *f,int *e)
{
int j,t;
for(j=0;!f[j];j++); //找第一个非空子表
sl[0].next=f[j]; //sl[0].next指向第一个非空子表中的一个结点
t=e[j];
while(j<radix_n-1)
{
for(j=j+1;j<radix_n-1&&!f[j];j++); //找下一个非空子表
if(f[j])
{
sl[t].next=f[j];
t=e[j];
} //链接两个非空子表
}
sl[t].next=0; //t指向最后一个非空子表中的最后一个结点
}
void distribute_c(slnode *sl,int i,int *f,int *e)
{
int j,p;
for(j=0;j<radix_c;j++)
{//各子表置为空表
f[j]=0;
e[j]=0;
}
for(p=sl[0].next;p!=0;p=sl[p].next)
{ j=sl[p].keys[i]%65; //将字母字符转换成在字母集中相应的序号(0-25)
if(!f[j])
f[j]=p;
else
sl[e[j]].next=p;
e[j]=p;
}
}
//一趟字母字符收集
void collect_c(slnode *sl,int *f,int *e)
{
int j,t;
for(j=0;!f[j];j++);
sl[0].next=f[j];t=e[j];
while(j<radix_c-1)
{
for(j=j+1;j<radix_c-1 && !f[j];j++);
if(f[j])
{
sl[t].next=f[j];
t=e[j];}
}
sl[t].next=0;
}
//链式基数排序函数
void radixsort(sllist *l)
{
int i;
int fn[10],en[10];
int fc[26],ec[26];
for(i=0;i<l->length;i++)
l->sl[i].next=i+1; //0号单元仅存放指针,不存储内容
l->sl[l->length].next=0; //将普通的线性表改造为静态链表
for(i=l->keynum-1;i>=2;i--)
{
distribute(l->sl,i,fn,en);
collect(l->sl,fn,en);
}
for(i=1;i>=0;i--)
{
distribute_c(l->sl,i,fc,ec);
collect_c(l->sl,fc,ec);
}
}
//按指针链重新整理静态链表
void arrange(sllist *l)
{
int p,q,i;
slnode temp;
p=l->sl[0].next; //p指向第一个记录的当前位置
for(i=1;i<=l->length;i++) //L.s1[1..i-1]已按关键字有序化/
{
while(p<i)
p=l->sl[p].next; //找到第i个记录,并用p指向其在L中当前位置
q=l->sl[p].next; //q指向尚未调整的表尾
if(p!=i)
{
temp=l->sl[p];l->sl[p]=l->sl[i];
l->sl[i]=temp; //交换记录
l->sl[i].next=p;
}
p=q; //p指向尚未调整的表尾,为找第i+1个记录做准备
}
}
int binsearch(sllist *l,keytype key[])
{
int low,high,mid;
low=1;high=l->length;
while(low<=high)
{ mid=(low+high)/2;
if(strcmp(key,l->sl[mid].keys)==0)
return mid;
else if(strcmp(key,l->sl[mid].keys)<0)
high=mid-1;
else low=mid+1;
}
return 0;
}
//顺序查找函数
void seqsearch(sllist *l,keytype key[],int i)
{
int j,k,m=0;
void display(sllist *l,int i);
for(j=1;j<=l->length;j++)
{
switch(i){
case 2:k=strcmp(key,l->sl[j].others.start);break; //起点站
case 3:k=strcmp(key,l->sl[j].others.end);break; //终点站
case 4:k=strcmp(key,l->sl[j].others.time1);break; //起飞时间
case 5:k=strcmp(key,l->sl[j].others.time2);break; //到达时间
}
if(k==0)
{
m=1;
display(l,j);
}
}
if(m==0)
printf("无此航班信息,可能是输入错误!\n");
}
void serachcon(sllist *l)
{ int i=1;
while(i>=1&&i<=5){
char key[keylen];
char ki[keylen];
int k;
printf("****************************\n");
printf("* 航班信息查询系统 *\n");
printf("****************************\n");
printf("* 1. 航 班 号 *\n");
printf("* 2. 起 点 站 *\n");
printf("* 3. 终 点 站 *\n");
printf("* 4. 起 飞 时 间 *\n");
printf("* 5. 到 达 时 间 *\n");
printf("* 0. 退 出 系 统 *\n");
printf("****************************\n");
printf(" 请选择 (0-5): ");
scanf("%d",&i);
switch(i){
case 1:printf("输入要查询的航班号(字母要大写):");
scanf("%s",key);k=binsearch(l,key);
display(l,k);
break;
case 2:printf("输入要查询的航班起点站名:");
scanf("%s",key);seqsearch(l,key,i);
break;
case 3:printf("输入要查询的航班终点站名:");
scanf("%s",key);seqsearch(l,key,i);
break;
case 4:printf("输入要查询的航班起飞时间:");
scanf("%s",ki);seqsearch(l,ki,i);
break;
case 5:printf("输入要查询的航班到达时间:");
scanf("%s",ki);seqsearch(l,ki,i);
break;
case 0:printf("再 见!\n");
return;
}
}
}
//输入航班记录函数
void inputdata(sllist *l)
{
int i=1;
char yn='y';
while(yn=='y'||yn=='Y')
{
printf("航班号 起点站 终点站 航班期 起飞时间 到达时间 机型 票价\n");
scanf("%s%s%s%s%s%s%s%d",l->sl[i].keys,l->sl[i].others.start,
l->sl[i].others.end,l->sl[i].others.sche,l->sl[i].others.time1,l->sl[i].others.time2,l->sl[i].others.model,&l->sl[i].others.price);
i++;
printf("要继续输入吗?y/n: ");
scanf("%s",&yn);
}
l->length=i-1;
}
void display(sllist *l,int i)
{ if(i!=0)
{
printf("航班号 起点站 终点站 航班期 起飞时间 到达时间 机型 票价\n");
printf("%s,%s,%s,%s,%s,%s,%s,%d\n",l->sl[i].keys,l->sl[i].others.start,
l->sl[i].others.end,l->sl[i].others.sche,l->sl[i].others.time1,l->sl[i].others.time2,l->sl[i].others.model,l->sl[i].others.price);
}
else printf("无此航班信息,可能是输入错误!\n");
}
void main()
{
sllist *l;
l=(sllist *)malloc(sizeof(sllist)); //初始化及输入数据
l->keynum=6;
l->length=0; //输入航班记录
inputdata(l); //基数排序
radixsort(l);
arrange(l); //调用查询函数
serachcon(l);
return;
}