1、中南大学信息科学与工程学院数据结构课程设计报告课题: 专业班级: 学号: 姓名: 指导老师: 完成时间: 一、 设计综述1设计题目航空客运订票系统2问题描述每条航线所涉及的信息有:终点站名、航班号、飞机号、飞机周日(星期几)、乘员定额、余票量、订定票的客户名单(包括姓名、订票量、舱位等级1,2或3)以及等候替补的客户名单(包括姓名、所需数量)。3.需求分析(1)查询航线:根据客户提出的终点站名输出如下信息:航班号、飞机号、星期几飞行,最近一天航班的日期和余票额;(2)承办订票业务:根据客户提出的要求(航班号、订票数额)查询该航班票额情况,若有余票,则为客户办理订票手续,输出座位号;若已满员或余
2、票少余订票额,则需重新询问客户要求。若需要,可登记排队候补;(3)承办退票业务:根据客户提出的情况(日期、航班号),为客户办理退票手续,然后查询该航班是否有人排队候补,首先询问排在第一的客户,若所退票额能满足他的要求,则为他办理订票手续,否则依次询问其它排队候补的客户。实现提示:两个客户名单可分别由线性表和队列实现。为查找方便,已订票客户的线性表应按客户姓名有序,并且,为了插入和删除方便,应以链表作为存储结构。由于预约人数无法预计,队列也应以链表作为存储结构。4完成目标通过对课程设计课题的研究,依靠自己的理解与学习,进行分析,设计,调试,记录等过程,深入了解数据结构(C语言)的知识与实践操作,
3、将两者相互结合,融会贯通。二、 程序设计1.概要设计1.1第一个结构体定义了订票客户passenger所需的全部变量;typedef struct passenger char name10;/*姓名*/ int ID20;/身份证号 int password; /密码 int tickets;/*订票量*/ struct passenger *next;qnode,*qptr;1.2第二个结构体用于创建候补客户的存储用循环链表;typedef struct pqueue qptr front; qptr rear;linkqueue;1.3第三个结构图定义了候补客户passenger_wai
4、t所需的全部变量;typedef struct passenger_wait char name10;/*客户姓名*/ int ID20;/身份证号 int tickets_wait;/*订票量*/ char grade;/*舱位等级*/ struct passenger_wait *next;linklist;1.4第四个结构体则定义了每趟航班所需的基本数据,这里可以初始化,但考虑到这是订票系统,于是没有添加新增航班功能。struct airline char ter_name10;/*终点站名 */ char air_num10;/*航班号*/ char plane_num10;/*飞机号
5、*/ char day7;/*飞行周日(星期几)*/ int tkt_amt;/*乘员定额*/ int tkt_sur;/*余票量*/ linklist *order;/*乘员名单域,指向乘员名单链表的头指针*/ linkqueue wait;/*等候替补的客户名单域* /lineinfo;2.订票系统架构:3.程序详细设计本程序包含:1.主函数2.主菜单函数3.航班信息查询函数(目的地查询函数、航班编号查询函数、航班时间查询函数)4.机票信息查询函数(顾客姓名查询、机票编号查询函数、航班编号查询)5.票卖出函数6.退票函数7.航班信息修改函数8.航班、机票信息文件判断建立函数9.航班、机票信
6、息文件保存函数。3.1 主函数(void main())主函数主要是调用其他函数,并把建立的链表头指针附给主菜单函数。首先调用航班、机票信息文件判断建立函数。它首先分别判断在是否存在航班信息文件、机票信息文件。如果不存在,分别生成文件(航班信息文件设为d:a.dat,机票信息文件设为d:b.dat),生成的文件中都已有初始数据。详细数据见3.1初始航班、机票文件内容。如果存在,则不再生成文件,而且不会变动已有的文件。然后它会分别读文件,分别生成航班信息的链表和机票信息链表,并将链表头返回到主函数的变量中。然后主函数调用主菜单函数,同时将两个链表头赋给主菜单函数。main航班信息文件判断生成函数
7、机票信息文件判断生成函数主菜单函数主函数流程图如下:3.2 主菜单函数(void menu(struct flight *f,struct ticket *t)主菜单函数是供用户选择下一步操作(函数),并把下一步需要的两个链表的头赋给该函数。主菜单流程图如下:航班信息查询主菜单函数选择输入ii1且i1且i1且i1且inextp中机票的姓名比较00非0非0输入查询的姓名打印p中机票信息打印“输入有误,重新输入”选择输入ii-1且inextpr中航班编号与输入编号的比较00非0非0打印pr中航班信息输入i选择switch(i)输入顾客信息相关航班信息赋予机票中生成机票编号主菜单函数航班剩余票数减1
8、储存两链表信息123.8 退票函数void return_tkt(struct flight *f,struct ticket *t) 退票函数是完成退票功能。由于在程序中唯一能够确定一张机票的变量为机票编号,所以在退票时候,要求输入要退的机票编号。程序遍历机票链表,搜索该机票,如果不存在,则输出“不存在该机票”;如果存在机票,打印机票信息,在确认退票后会删除该条机票信息,并且在该票对应的航班的剩余票数上加1。然后程序将两链表写入文件中。完成退票后,程序返回主菜单。退票函数流程图(p是struct ticket型指针,赋初值为机票信息链表头)退票函数输入机票编号p!=NULLLp=p-next
9、p中航班编号与输入编号的比较00非0非0打印p中机票信息输入i选择switch(i)删除该机票主菜单函数航班剩余票数加1储存两链表信息124. 源代码清单/王骞 通信1103班 0909111423 航空售票系统 #include #include #include #define MAXSIZE 10 typedef struct passenger_wait char name10;/*姓名*/ char ID20;/身份证号 char phone11; /电话 int tickets_wait;/*订票量*/ struct passenger_wait *next;qnode,*qptr
10、;typedef struct pqueue qptr front;/*等候替补客户名单域的头指针*/ qptr rear;/*等候替补客户名单域的属指针*/linkqueue;typedef struct passenger_ready char name10;/*客户姓名*/ char ID20;/身份证号 char phone11; /电话 int tickets_ready;/*订票量*/ char grade;/*舱位等级*/ struct passenger_ready *next;linklist;struct airline char ter_name10;/*终点站名 */
11、char air_num10;/*航班号*/ char plane_num10;/*飞机号*/ char day7;/*飞行周日(星期几)*/ int tickets_total;/*乘员定额*/ int tickets_left;/*余票量*/ linklist *book;/*乘员名单域,指向乘员名单链表的头指针*/ linkqueue wait;/*等候替补的客户名单域,分别指向排队等候名单队头队尾的指针*/lineinfo;struct airline *start;/函数申明void search();void display();void prtlink();void book()
12、;void return_tkt();int menu_select()/*菜单界面*/ int c; char s20; system(color 1B);system(cls); puts(t *航空售票系统*n); puts(tt 查询: 1.浏览航线信息 ); puts(tt 2.浏览已订票客户信息 ); puts(tt 3.查询航线 nn); puts(tt 订购: 4.办理订票业务 ); puts(tt 5.办理退票业务 nn); puts(tt 退出: 6.退出系统 ); puts(t *); printf(t 请从1-6中选择操作: ); do scanf(%s,s); c=a
13、toi(s); while(c7); return c;main() struct airline airMAXSIZE=北京,1, BJ7001, 周日,70,60, 广州,2, GZ5002, 周五,60,50, 香港,3, HK4003, 周四,100,77, 重庆,4, CQ3004, 周三,90,68, 乌鲁木齐,5, WL1005, 周一,50,29, 昆明,6, KM6006, 周六,80,71, 遵义,7, GY3007, 周三,50,38, 长沙,8, CS7008, 周日,40,24, 台北,9, TP2009, 周二,30,17, 杭州,10, HZ5010, 周五,60
14、,25, ;/*初始化航线信息*/ /* clrscr();*/ start=air; for(;) switch(menu_select() case 1:list();break; case 2:prtlink();break; case 3:search();break; case 4:book();break; case 5:return_tkt();break; case 6:system(cls) ; printf(nttt欢迎再次使用,再见!n);exit(0); printf(nnttt按任意键返回主菜单!n); getch(); system (cls); void disp
15、lay(struct airline *info)/*打印每条航线的基本信息*/printf(%8st%3st%st%4stt%3dt%10dn,info-ter_name,info-air_num,info-plane_num,info-day,info-tickets_total,info-tickets_left);void list()/*打印全部航线信息*/ system(cls); struct airline *info; int i=0; info=start; printf(nnnn 终点站名t航班号t飞机号t飞行周次t乘员定额t余票量n); while(iMAXSIZE)
16、display(info); info+; i+; printf(nn);void search()/*根据客户提出的终点站名输出航线信息*/system(cls) ; struct airline *info,*find(); char name10; int i=0; info=start; printf(ntt请输入终点站名:); scanf(%s,name); while(iter_name) break; info+; i+; if(i=MAXSIZE) system(cls); printf(nnnnnttt对不起,该航线未找到!n); else printf(nnnn 终点站名t
17、航班号t飞机号t飞行周日t乘员定额t余票量n); display(info); struct airline *find()/*根据系统提出的航班号查询并以指针形式返回*/ struct airline *info; char number10; int i=0; info=start; printf(ntt请输入航班号:); scanf(%s,number); while(iair_num) return info; info+; i+; system(cls); printf(nnnnnnttt对不起,该航线未找到!n); return NULL;void prtlink()/*打印订票乘
18、员名单域的客户名单信息*/ system(cls) ; linklist *p; struct airline *info; info=find(); p=info-book; if(p!=NULL) printf(nnnntt客户姓名 订票数额 舱位等级n); while(p) printf(tt%stt%dt%dn,p-name,p-tickets_ready,p-grade); p=p-next; else printf(nttt该航线没有客户信息!n);linkqueue appendqueue(linkqueue q,char name,int amount)/*增加排队等候的客户名
19、单域*/ qptr new; new=(qptr)malloc(sizeof(qnode); strcpy(new-name,name); new-tickets_wait=amount; new-next=NULL; if(q.front=NULL)/*若原排队等候客户名单域为空*/ q.front=new; else q.rear-next=new; q.rear=new; return q;linklist *insertlink(linklist *head,int amount,char name,int grade)/*增加订票乘员名单域的客户信息*/ linklist *p1,*
20、new; p1=head; new=(linklist *)malloc(sizeof(linklist); if(!new) printf(nOut of memory!n);return NULL; strcpy(new-name,name); new-tickets_ready=amount; new-grade=grade; new-next=NULL; if(head=NULL)/*若原无订票客户信息*/ head=new;new-next=NULL; else head=new; new-next=p1; return head;void book()/*办理订票业务*/ syst
21、em(cls) ; struct airline *info; int amount,grade; char name10; char ID20; char phone20; info=start; if(!(info=find() return;/*根据客户提供的航班号进行查询,如为空,退出该模块*/ printf(tt请输入你订票所需要的数量:); scanf(%d,&amount); if(amountinfo-tickets_total)/*若客户订票额超过乘员定票总额,退出*/ printf(ntt对不起,您输入的票的数量已经超过乘员定额!n); return; if(amountt
22、ickets_left)/*若客户订票额末超过余票量,订票成功并等记信息*/ int i; printf(tt请输入订票客户的姓名:); scanf(%s,name); printf(tt请输入%s身份证号(18位):,name); scanf(%s,ID); printf(tt请为%s的联系电话:,name); scanf(%s,phone); printf(tt请输入%s的舱位等级(1、2或3):,name); scanf(%d,&grade); info-book=insertlink(info-book,amount,name,grade);/*在订票乘员名单域中添加客户信息*/ fo
23、r(i=0;itickets_total-info-tickets_left+i+1); info-tickets_left-=amount;/*该航线的余票量应减掉该客户的订票量*/ printf(nnnttt订票成功,祝您乘坐愉快!n); else /*若满员或余票额少于订票额,询问客户是否需要进行排队等候*/ char r; printf(tt已经没有更多的票,您需要排队等候吗?(Y/N); r=getch(); printf(%c,r); if(r=Y|r=y) printf(ntt请输入您的姓名(排队订票客户):); scanf(%s,name); printf(ntt请输入您的手机
24、号:); scanf(%s,phone); info-wait=appendqueue(info-wait,name,amount);/*在排队等候乘员名单域中添加客户信息*/ system(cls); printf(nnnnt注册成功!nnt如果有乘客退票我们会及时通知您,请您保持手机畅通,谢谢!n); else printf(nttt按任意键返回主菜单n); void return_tkt()/退票业务 system(cls) ; struct airline *info; qnode *t,*back,*f,*r; int grade; linklist *p1,*p2,*head; c
25、har cusname10; if(!(info=find() return;/*调用查询函数,根据客户提供的航线进行搜索*/ head=info-book; p1=head; printf(tt请输入你的姓名(退票客户):); scanf(%s,&cusname); while(p1!=NULL)/*根据客户提供的姓名到订票客户名单域进行查询*/ if(!strcmp(cusname,p1-name) break;/根据输入的身份证比对,找到要退票的乘客 /注意,phone要用的是指针,strcmp和=都需要相同格式才能比较 p2=p1;p1=p1-next;/没有找到 指针下移 if(p1
26、=NULL) printf(nttt对不起,你没有订过票!n);return;/*若未找到,退出本模块*/ else /*若信息查询成功,删除订票客户名单域中的信息*/ if(p1=head) head=p1-next;/查找到的顾客在链表的第一个节点 else p2-next=p1-next;/查找到的顾客不是在第一个节点 info-tickets_left+=p1-tickets_ready; grade=p1-grade; system(cls); printf(nttt%s退票成功!,p1-name); free(p1); info-book=head;/*重新将航线名单域指向订票单链
27、表的头指针 */ f=(info-wait).front;/*f指向排队等候名单队列的头结点*/ r=(info-wait).rear;/*r指向排队等候名单队列的尾结点*/ t=f;/*t为当前满点条件的排队候补名单域*/ while(t) if(info-tickets_left=info-wait.front-tickets_wait)/*若满足条件者为头结点*/ int i; info-wait.front=t-next; /printf(nnnnnttt%s订票成功!n,t-name); /for(i=0;itickets_wait;i+)/*输出座位号*/ /printf(nttt
28、%s的座位号是:%d,t-name,(info-tickets_left)-i); info-tickets_left-=t-tickets_wait; info-book=insertlink(info-book,t-tickets_wait,t-name,grade);/*插入到订票客户名单链表中*/ free(t); break; back=t;t=t-next; if(info-tickets_left)=(t-tickets_wait)&t!=NULL)/*若满足条件者不为头结点*/ int i; back-next=t-next; system(cls); /printf(nnnn
29、nn%sttt订票成功!n,t-name); /for(i=0;itickets_wait;i+)/*输出座位号*/ /printf(nttt的座位号是:%dn,t-name,(info-tickets_left)-i); info-tickets_left-=t-tickets_wait; info-book=insertlink(info-book,t-tickets_wait,t-name,grade);/*插入到订票客户名单链表中*/ free(t);break; if(f=r) break; 5.程序调试详细过程初始界面:浏览航线:查询航班:订票:查询订票结果:候选选择:退票:6.实
30、验心得相比大一的课程设计学生成绩管理系统,这次做的航空订票系统简直和它不是一个层次,不仅要求了链表数组的建立,还引入了许多数据结构中的先进思想,学懂容易,实践难。经过接近十周的软件程序设计。在结束时回顾整个编写过程,我发现程序的主体基本上是在第三周才开始出现的。由于第一周确定了大概的思路,但是更重要的是要进行对于文件操作,链表操作的方面内容的学习。第二周开始尝试着写了一些函数,试运行。这一周对于文件与链表有了更加深刻的认识,这一点非常重要。第一周学习的东西真正运用到程序上时候经常出现各种问题。经过两周的积淀,第三周开始写真正的程序,应该说还是比较快的。但是最为主要的问题就是在编程序过程中式不断
31、的遇到BUG。虽然程序主体写完了,但是对于BUG的修改,则很费时间。有时候认为很简单的一个要求,化为语句后很难做到,或者做得容易出错。这几周的学习真正将C语言应用出去,这也蛮有意思的。如同一门外语,与老外交流的过程总是比习题要有趣,但是总会有误解、BUG出现。整个编写过程来看,大量应用链表、文件、指针操作,特别是由于对于这些并不能够游刃有余地使用,导致在编写时候,容易遇到各种问题。也许只是不经意间的一个问题都会带来很多的BUG,甚至使程序出错。程序编写过程中算法并不能一次写到完美,总是不断地调试。而调试过程可能比编写过程更加费时。但是可以使程序更加完善。 所幸的是,课题总算在期限之前完成了,受益匪浅,加深了我对C语言基础的理解,也拓展了我对C语言数据管理的高级用法数据结构的视野,可谓收获颇丰。