航班信息的查询与检索

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

航班信息的查询与检索
目录 (3)
1 概述 (3)
1.1 课程设计名称 (3)
1.2 课程设计目的 (3)
1.3 课程设计内容 (3)
2 系统分析 (3)
2.1 设计要求 (3)
2.2 设计分析 (4)
3 概要设计 (4)
3.1 系统总流程图 (4)
3.2 定义数据类型 (5)
3.3 实现排序的各函数的说明 (7)
4 详细设计 (8)
4.1 数据类型的定义 (8)
4.2 链式基数排序 (9)
4.2.1 一趟数字字符分配函数 ............. 错误!未定义书签。

4.2.2 一趟数字字符的收集函数.......... 错误!未定义书签。

4.2.3 一趟字母字符分配函数 ............. 错误!未定义书签。

4.2.4 一趟字母字符收集 .................... 错误!未定义书签。

4.2.6 链式基数排序函数 .................... 错误!未定义书签。

4.3 重新整理静态链表 (10)
4.4 查找算法实现 (11)
4.4.1 二分查找函数 (11)
4.4.2 顺序查找函数 (12)
4.5 输入输出函数 (13)
5 运行与测试 (16)
6 总结与心得 (19)
7 参考文献 (20)
8 附录(程序源代码) (20)
目录
1 概述
1.1 课程设计名称
航班信息的查询与检索
1.2 课程设计目的
通过本次实验,掌握数据结构中的几种排序算法和查找算法,了解静态链表的运用,利用上述的算法完成航班信息的查询与检索。

2 系统分析
2.1 课程设计内容
本课程设计主要是对排序及查找等进行练习,以链式基数排序为主线,利用二分查找和顺序查找等知识,并建立静态链表,完成对航班信息的查询与检索。

我们可以利用航班的这些信息,通过其中的任意一个信息,找出我们所需要的查找的航班的所有信息,所以,我们可以采用基数排序法对一组具有结构特点的飞机航班号进行排序,利用二分查找法对排序好的航班记录按航班号实现快速查找,并按其他关键字的查找可以采用最简单的顺序查找方法进行。

2.2 设计要求
1) 提供对航班信息的排序功能
2 提供对航班信息的输入输出记录功能找出我们所需要的查
找的航班的所有信息
3)提供按关键字(航班号)快速查询或顺序查询功能
2.3 设计分析
对于本设计,可采用基数排序法对一组具有结构特点的飞机航班号进行排序,利用二分查找法对排好序的航班记录按航班号实现快速查找,按其他次关键字的查找可采用最简单的顺序查找方法进行,因为它们用得比较少。

每个航班记录包括八项,分别是:航班号,起点站,终点站,班期,起飞时间,到达时间,飞机型号以及票价等。

其中航班号一项的格式为:
K0 k1 k2 k3 k4 k5
航班关键字可分为两段,即字母和数字。

其中k0和k1是航空公司的别称,用两个大写字母表示,后4位为航班编号。

3 概要设计
3.1 系统总流程图
3.2 定义数据类型
根据设计要求,设计中所用到的数据记录只有航班信息,因此要定义相关的数据类型:typedef struct {
char start[7]; //起点
char end[7]; //终点
char sche[12]; //班期
char time1[5]; //起飞时间
char time2[5]; //到达时间
char model[4]; //机型
int price;
//票价
}InfoType;
//航班记录类型
typedef struct{
KeyType keys[keylen]; //关键字
InfoType others;
int next;
}slnode;
//表结点
typedef struct{
SLNode sl[MaxSpace]; //静态链表,s1[0]为头结点
int keylen; //关键字长
int length; //当前表长
}SLList;
//静态链表类型
为了进行基数排序,需要定义在分配和收集操作时用到的指针数组:
typedef int ArrType_n[10]; //十进制数字指针数组
typedef int ArrType_c[26]; //26个字母指针数组
3.3 实现排序的各函数的说明
1)一趟分配函数:
void Distribute(SLNode *s1,int i,ArrType f,ArrType e);
//本算法是按关键字key[i]建立RADIX个子表,使同一个子表中记录的keys[i]
//相同,f[0..RADIX]和e[0..RADIX]分别指向各子表中的第一个和最后一个记录
2)一趟搜集函数:
void Collect(SLNode *s1,int i,ArrType f,ArrType e);
//本算法是按关键字keys[i]从小到大将[0..RADIX]所指的各子表依次链接成一个链表
3)链式基数排序函数:
void RadixSort(SLList &L);
//本算法是按关键字从低位到高位依次对各关键字进行分配和收集,分两段实现
4)二分查找函数:
int BinSearch(SLList L,KeyType key[]);
//L为待查找的表,key[]为待查找的关键字,按二分查找的思想实现查找
5)主控函数
void main()
{
初始化;
数据输入;
排序处理;
接受查找要求及查找关键字;
查找处理;
输出查找结果;
}
4 详细设计
4.1 数据类型的定义
根据设计要求我们知道所用的记录中只有航班信息因此要定义相关的数据类型其源程序如下
typedef struct
{
char start[6];//起点
char end[6]; //终点
char sche[10];//班期
char time1[5];//起飞时间
char time2[5];//到达时间
char model[4];//机型
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; //静态链表类型
typedef int arrtype_n[radix_n];//十进制数字指针typedef int arrtype_c[radix_c];//26个字母指针4.2 链式基数排序

输入数据、基数、长度
改造为
对关键字


4.3 重新整理静态链表
重新整理静态链表,P 指示第一个记录的当前位置,L.s1[1..i-1]已按关键字有序排列 ,第一个记
录在L中的当前位置应不小于i,使用while循环,找到第i个记录,并用p指示其在L中的当前位置,而q指示尚未调整的表尾,若if(p!=i) 则p指向被移走的记录,使得以后可由while循环找回,当p=q时,p指向尚未调整的表尾,为找到第i+个记录做准备
4.4 查找算法实现
4.4.1 二分查找函数


4.4.2 顺序查找函数
void SeqSearch(SLList L,KeyType key[],int i) { int j,k,m=0;
for(j=1;j<L.length;j++)
{ switch(i) {
case
2:k=strcmp(key,L.s1[j].others.start);break;
case
3:k=strcmp(key,L.s1[j].others.end);break;
case
4:k=strcmp(key,L.s1[j].others.time1);break;
case
5:k=strcmp(key,L.s1[j].others.time2);break;
}
if(k==0)
{ m=1;Display(L,j);}
}
if(m==0)
printf("无此航班信息,可能是输入错误!\n"); }
4.5 输入输出函数
serachcon(SLList L)
{
int i=1,k,k1;
while(i>=1 && i<=5) {
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:\n ");
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",k1); SeqSearch(L,k1,i);
break;
case 5: printf("输入要查询的航班到达时间:"); scanf("%s",k1); SeqSearch(L,k1,i);
break;
case 0: printf("再见!\n");
return 0;
}
}
}
void InputData(SLList &L)
{ int i=++L.length;
char yn='y';
while(yn=='y' || yn=='Y')
{ printf("航班号起点站终点站航班期起飞时间到达时间机型票价\n");
scanf("%s%s%s%s%s%s%s%d",L.s1[i].keys,L. s1[i].others.start,
L.s1[i].others.end,L.s1[i].others.sche,L.s1[i].others .time1,
L.s1[i].others.time2,L.s1[i].others.model,&L.s1[i]. others.price);
++i;
printf("继续输入吗?y/n: \n");
scanf("%c",&yn);
}
L.length=i-1;
}
5 运行与测试
航班信息输入如图:
按航班号查询:
输入航班号错误则显示如下图:
按航班起点站查询:
按起飞时间查询:
显示查询主菜单,退出查询系统:
6 总结与心得
通过本实验,我了解了基数排序是作为一种内部排序方法,当关键字位数较少而排序序列较长时,该排序算法有一定的优越性。

而对于有序序列的查找算法,二分查找是一种效率比较高的方法。

在本实验中,对这两种算法的应用,我加深了对他们的理解,掌握了他们的实现方法。

在本次实验过程中,输入错误还是存在的问题,但能很快的通过编译解决,一些编译不能发现的问题,在组建过程中也能发现并解决。

这次实验的过程中遇到了很多问题,定义的过程中存在定义不清楚的问题,还有一些模糊定义和重定义的问题出现。

在程序的定义过程中,存在着函数的调用失败的问题,在调用过程中不能正常调用,通过把调用的函数直接用在程序中,不通过调用的方法,使得程序正常运行。

本次实验的问题只要通过调试和对整个程序的理解,便可以解决所有的发现的问题本次实验利用二分查找法很快的完成了对航
班信息的查找,使我们对二分查找有了一个很好的掌握。

其查找过程是先确定待查记录所在的范围(区间),然后逐步缩小范围直到找到或找不到该记录为止。

在实验过程中,程序中许多定义需要我们有一个很仔细的了解,比如上述的对字符长度的定义,这需要对所定义的对象给一个合理的字符长度,在输入的过程中才不会出现因输入的字符长度过长而不能识别。

本次实验中用到了静态链表,定义静态链表的过程中,需要有一个很熟悉的了解,知道静态链表是如何定义以及如何实现。

通过这次实验,使得对于查找以及检索有了一个很好的掌握,让我们在以后的程序设计过程中对于类似的函数定义有一个很清晰的过程以及了解。

7 参考文献
1)徐孝凯,魏荣《数据结构》,机械工程出版社
2) 谭浩强《程序设计》,北京大学出版社
3) 杨路明《C语言程序设计教程》,北京邮电大学出版社.
4) 耿国华《数据结构-C语言描述》,高等教育出版社
8 附录(程序源代码)
#include <stdio.h>
#include <string.h>
#define MaxSpace 100
#define keylen 7
#define RADIX_n 10
#define RADIX_c 26
typedef char KeyType;
typedef struct
{
char start[6]; //起点
char end[6]; //终点
char sche[10]; //班期
char time1[5]; //起飞时间
char time2[5]; //到达时间
char model[4]; //机型
int price; //票价
}InfoType; //航班记录类型
typedef struct
{
KeyType keys[keylen]; //关键字(航班号)InfoType others;
int next;
}SLNode; //静态链表结点类型typedef struct
{
SLNode sl[MaxSpace]; //静态链表,s1[0]为头结点
int keynum; //记录当前关键字字符个数
int length; //当前表长
}SLList; //静态链表类型typedef int ArrType_n[RADIX_n]; //十进制数字指针数组
typedef int ArrType_c[RADIX_c]; //26个字母指针数组
// 一趟数字字符分配函数
void Distribute(SLNode *sl,int i,ArrType_n f,ArrType_n e)
{
int j,p;
for(j=0;j<RADIX_n;j++)
{ //各子表置为空表
f[j]=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 i,ArrType_n f,ArrType_n e)
{
int j,t;
for(j=0;!f[j];j++) //找第一个非空子表
sl[0].next=f[j]; //s1[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,ArrType_c f,ArrType_c e)
{
int j,p;
for(j=0;j<RADIX_c;j++)
{ //各子表置为空表
f[j]=e[j]=0;
}
for(p=sl[0].next;p;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 i,ArrType_c f,ArrType_c 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;
ArrType_n fn,en;
ArrType_c fc,ec;
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--)
{ //按最低位优先次序对各关键字进行分配和收集,先做低4位数字部分
Distribute(L.sl,i,fn,en);
Collect(L.sl,i,fn,en);
}
for(i=1;i>=0;i--)
{ //对高位的2位大写字母进行分配和收集Distribute_c(L.sl,i,fc,ec);
Collect_c(L.sl,i,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;
printf("************************************ *************************\n");
printf("* 航班号起点站终点站航班期起飞时间到达时间机型票价*\n");
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;
printf("* %-8s%-7s%-6s%-11s%-9s%-7s%-5s% 4d *\n",L.sl[j].keys,L.sl[j].others.start,L.sl [j].others.end,L.sl[j].others.sche,L.sl[j].others.time 1,L.sl[j].others.time2,L.sl
[j].others.model,L.sl[j].others.price);
}
}
if(m==0)
printf("* 无此航班信息,可能是输入错误!*\n"); printf("************************************ *************************\n");
}
// 查询检索菜单控制程序
void searchcon(SLList L)
{
KeyType key[keylen];
int i=1,k;
while(i>=1&&i<=5)
{
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): \n");
scanf("%d",&i);
switch(i)
{
case 1:printf("输入要查询的航班号(字母要大写):");
scanf("%s",key);
k=BinSearch(L,key);
printf("************************************ *************************\n");
if(k==0)
printf(" 无此航班信息,可能是输入错误!\n"); else
{
printf("* 航班号起点站终点站航班期起飞时间到达时间机型票价*\n");
printf("* %-8s%-7s%-6s%-11s%-9s%-7s%-5s% 4d *\n",L.sl[k].keys,L.sl[k].others.start,L.sl [k].others.end,L.sl[k].others.sche,L.sl[k].others.ti me1,L.sl[k].others.time2,L.sl
[k].others.model,L.sl[k].others.price);
}
printf("************************************ *************************\n");
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",key);
SeqSearch(L,key,i);
break;
case 5:printf("输入要查询的航班到达时间:");
scanf("%s",key);
SeqSearch(L,key,i);
break;
case 0:printf("再见\n");
}
}
}
// 输入航班记录函数
void InputData(SLList &L)
{
int i=++L.length;
char yn='y';
while(yn=='y'||yn=='Y')
{
printf("航班号起点站终点站航班期起飞时间到达时间机型票价\n");
scanf("%s%s%s%s%s%s%s%d",L.sl[i].keys,L.s l[i].others.start,L.sl[i].others.end,L.sl
[i].others.sche,L.sl[i].others.time1,L.sl[i].others.ti me2,L.sl[i].others.model,&L.sl
[i].others.price);
++i; getchar();
RadixSort(L);
Arrange(L);
printf("继续输入吗?y/n:");
scanf("%c",&yn);
}
L.length=i-1;
}
void main()
{
// int i,k;
SLList L;
// KeyType key[keylen];
L.keynum=6; L.length=0; //输入航班记录
InputData(L); //基数排序
RadixSort(L);
Arrange(L);
searchcon(L);
return ;
}。

相关文档
最新文档