1、目录1. 需求分析12. 概要设计23. 详细设计64. 测试与分析145. 用户使用说明196. 总结20参考文献201. 需求分析1.1 问题描述基于目前人们外出远行频繁,为方便乘客提前买票及优化飞机航空订票服务,需要开发一个飞机订票系统,此程序就是要实现航班情况的录入,查询,订票,退票以及航班的查询和修改等基本功能。本课程设计的题目为:飞机订票系统。1.2 基本要求1.2.1 输入的形式和输入值的范围录入航班信息时,需要输入航班号,起降时间,起飞抵达城市,值为字符串;还需要输入航班票价,票价折扣,值为浮点型(float);还需要输入航班是否满仓,值为整型(int)(“1”表示已满仓,“0
2、”表示没有满仓);如需要继续录入航班信息,要输入判别信息,值为整型(“1”表示继续录入航班信息,“0”表示停止录入航班信息)。客户订票时,需要输入起飞抵达城市,然后选择航班进行查询,选择航班时需要输入航班号,值为字符串。客户退票时,需要输入姓名,证件号进行退票操作,值为字符串。查询某个航班的情况时,需要输入航班号,值为字符串;在查询某个航线的情况时,还可以通过输入起飞抵达城市来查询,值为字符串。查询某个订单时,需要输入订单号,值为整型(int);或者需要输入客户姓名和证件号,值为字符串。修改航班时,需要输入字符型数据选择进行何种修改操作;增加航班时,需要输入航班号,起降时间,起飞抵达城市,值为
3、字符串;还需要输入航班票价,票价折扣,值为浮点型(float);还需要输入航班是否满仓,值为整型(int)(“1”表示已满仓,“0”表示没有满仓);如需要继续录入航班信息,要输入判别信息,值为整型(“1”表示继续录入航班信息,“0”表示停止录入航班信息);删除航班时,需要输入要删除的航班的航班号;修改航班时间时,需要输入要修改的航班的航班号,修改后的航班起飞时间和抵达时间。1.2.2 输出形式在所有操作后的输出中都显示操作是否正确以及操作后单链表的内容。其中删除操作后显示删除的元素的值,查找操作后显示要查找元素的位置。录入航班情况时,输出显示添加航班信息是否成功。客户订票时,当客户输入起飞抵达
4、城市后,输出可供客户选择的航班信息;客户选择了航班后,输入提示信息告知用户订票是否成功。客户退票时,输出客户退票成功或者无此客户,无法退票。查询航班时,输出显示对应的航班信息,或者输出提示信息告知没有相应的航班信息。查询订单时,输出显示对应的订单信息,或者输出提示信息告知没有相应的订单信息。修改航班时,输出对应的提示的信息,提示操作是否成功。1.2.3 功能要求(1)可以录入航班情况,数据存储在一个数据文件中;(2)可以查询某个航线的情况:输入航班号,查询起降时间,起飞抵达城市,航班票价,票价折扣,确定航班是否满仓;输入起飞抵达城市,查询飞机航班情况;(3)可以订票,订票情况存在一个数据文件中
5、(如果该航班已经无票,提供相关可选航班);(4)可退票并且退票后修改相关数据文件;(5)客户资料:姓名,证件号,订票数量及航班情况,订单要有编号;(6)修改航班信息,当航班信息改变可修改航班数据文件;(7)要求:根据以上功能说明,设计航班信息,订票信息的存储结构,设计程序完成功能。2. 概要设计2.1 数据结构(1)航班的信息:航班的情况存储结构采用单链表,每个元素表示一个航班的情况,包括航班号、起飞时间、降落时间、起飞城市、抵达城市、航班票价、票价折扣、确定航班是否满仓和空座数九个数据项:航班号起飞时间降落时间起飞城市抵达城市航班是否满仓空座数票价票价折扣字符串字符串字符串字符串字符串整数(
6、int)整数(int)浮点数(float)浮点数(float)单链表如下:D1D2D3 h每个结点包括数据域和指针域:数据域指针域C语言描述如下:typedef struct flightnodechar air_num10;/航班号char start_time15;/起飞时间char end_time15;/抵达时间char start_place20;/起飞城市char end_place20; /降落城市int left; /空座数float price; /票价float price_discount;/票价折扣int isFull; /航班是否满仓struct flightnode
7、 *next;/指向下一个结点flightnode;/航班结点(2)客户的资料:为了便于插入、删除和修改,其采用单链表存储结构,每个数据元素包括姓名、证件号、航班号、订票数量和订单号五个数据项:姓名证件号航班号订票数量订单号字符串字符串字符串整数(int)整数(int)每个结点包括数据域和指针域:数据域指针域C语言描述如下:typedef struct passengernode/定义客户资料结点char name20; /姓名char ID_num20; /证件号char flight_num10;/航班号int order_num; /订单号int ticket_num; /订票数量str
8、uct passengernode *next;/指向下一个结点passengernode;(3)客户链表:每个数据元素包括头指针和尾指针两个数据项:每个结点包括两个指针域:头指针域尾指针域C语言描述如下:typedef struct passengerListpassengernode *head;passengernode *rear;passengerList;2.2 程序模块2.2.1 录入航班信息模块void add_flight(flightnode *&h)调用void insert_flight(flightnode *&h,char* flight_num,char* sta
9、rt_place,char* end_place,char* start_time,char* end_time,int left,float price,float price_discount,int isFull)函数,将新航班结点插入航班链表中。2.2.2 客户订票模块int book(flightnode *&h,passengerList *&PList)函数调用int insert_passenger(passengernode *&h,char *name,char *ID_num,char *flight_num,int ticket_num,int order_num)函数
10、,将新客户结点插入客户链表中。2.2.3 客户退票模块void cancel(passengerList *&PList,flightnode *&h)函数调用int delete_passenger(passengerList *&PList,flightnode *&h,char *name,char *ID_num)函数,将相应的顾客结点删除,并修改相应的航班信息。2.2.4 查询航班模块void flight_check(flightnode *h)调用void check_all_flight(flightnode *h)函数进行所有航班信息浏览,调用int place_check(
11、flightnode *h,char *start_place,char *end_place)函数按起飞抵达城市对航班进行查询,调用int flight_num_check(flightnode *h,char *flight_num)按航班号对航班进行查询。2.2.5 查询订单模块void passenger_check(passengerList *PList)调用void check_all_passenger(passengerList *PList)函数进行所有订单信息浏览,调用int order_num_check(passengerList *PList,int order_n
12、um)函数按订单号对订单进行查询,调用int ID_name_check(passengerList *PList,char *name,char *ID_num)按客户姓名和证件号对订单进行查询。2.2.6 修改航班模块增加航班时,void modify_flight(flightnode *&h,passengerList *&PList)函数调用void add_flight(flightnode *&h)函数,将新航班信息结点插入航班链表中。删除航班时,void modify_flight(flightnode *&h,passengerList *&PList)函数调用void de
13、lete_flight(flightnode *&h,passengerList *&PList)函数将相应的航班信息删除,并删除相应的订单信息。修改航班时间时,void modify_flight(flightnode *&h,passengerList *&PList)函数修改指定航班的起飞抵达时间。2.3 各模块之间的调用关系以及算法设计2.3.1 各模块之间的调用关系主函数录入航班信息订 票退 票查询航班查询订单修改航班信息退 出浏览全部航班信息按起飞抵达城市查询航班信息按航班号查询航班信息浏览全部订单信息按客户姓名和证件号查询订单信息按订单号查询订单信息增加航班信息修改航班起飞抵达时
14、间删除航班信息2.3.2 算法设计void init_flight(flightnode *&h):要建立一个以h为头结点的空链表,录入航班信息和增加航班后将航班结点插入该链表。void init_passengerList(passengerList *&pList):建立一个带有头指针和尾指针的空链表,存储带有顾客信息的结点。void save_flight(flightnode *h):保存航班信息到指定数据文件中。void load_flight(flightnode *&h):从存储航班信息的文件导入航班信息到航班链表中。void save_passenger(passengerLi
15、st *PList):保存客户信息到指定数据文件中。void load_passenger(passengerList *&PList):从存储客户信息的文件导入客户信息到客户链表中。void add_flight(flightnode *&h):录入航班信息后调用insert_flight函数增加航班。void insert_flight(flightnode *&h,char* flight_num,char* start_place,char* end_place,char* start_time,char* end_time,int left,float price,float pri
16、ce_discount,int isFull):在录入航班情况或增加新的航班后,将新的航班结点插入到航线链表中。int book(flightnode *&l,passengerList *&PList):要完成客户订票,将客户结点插入客户链表中,并修改相应的航班信息。void insert_passengerList(flightnode *&h,passengerList *&PList,char *name,char *ID_num,char *flight_num,int ticket_num):在顾客订票后,将该顾客结点插入到顾客链表中,并修改相应的航班信息。void find_sa
17、me_flight(flightnode *l,char *flight_num):在客户订票时,当客户输入的航班号对应的航班已满仓时,提供其他可选航班并输出显示。void cancel(passengerList *&PList,flightnode *&h):完成客户退票,将客户的订单从客户链表中删除,并修改相应的航班信息。int delete_passenger(passengerList *&PList,flightnode *&h,char *name,char *ID_num):按照要退票的顾客的姓名和证件号查找该顾客结点,进行删除操作。void flight_check(flig
18、htnode *h):选择使用何种方式对航班信息进行查询。void check_all_flight(flightnode *l):浏览所有航班信息。int place_check(flightnode *l,char *start_place,char *end_place):按照起飞抵达城市查询航班信息。int flight_num_check(flightnode *l,char *flight_num):按照航班号查询航班信息。void passenger_check(passengerList *PList):选择使用何种方式对订单信息进行查询。void check_all_pass
19、enger(passengerList *PList):浏览所有订单信息。int order_num_check(passengerList *PList,int order_num):按订单号查询订单信息。int ID_name_check(passengerList *PList,char *name,char *ID_num):按客户姓名和证件号查询订单信息。void modify_flight(flightnode *&h,passengerList *&PList):修改航班信息,包括添加航班信息,删除航班信息,修改航班起飞抵达时间。void delete_flight(flight
20、node *&h,passengerList *&PList):按照某个航班号删除航班结点。3. 详细设计3.1 录入航班信息模块在主函数中输入“1”,调用void add_flight(flightnode *&h)函数,此函数将航班指针*p指向已存在航班链表*h的头结点,利用for(;p-next!=NULL;p=p-next)使*p指向航线链表的最后一个结点,然后让用户输入航班信息,然后调用void insert_flight(flightnode *&h,char* flight_num,char* start_place,char* end_place,char* start_tim
21、e,char* end_time,int left,float price,float price_discount,int isFull)函数,用malloc函数申请一个航班结点,并用指针*q指向,将航班信息赋到新申请的结点中,p-next=q;p=p-next;该操作将该结点插入航班链表中。流程图如下:YYflightnode *p=h;p-next!=NULLp=p-nextmark=1输入航班信息调用insert_flight函数完成航班信息的录入是否继续录入航班信息“是”输入“1”mark=1“否”输入“0”mark=0开始结束NN3.2 顾客订票模块在主函数中输入“2”,调用int
22、 book(flightnode *&h,passengerList *&PList)函数完成客户的订票。用航班指针*p指向已存在航班链表*h的头结点的下一个结点,请客户输入起飞抵达城市,分别存于start_place和end_place中。调用int place_check(flightnode *l,char *start_place,char *end_place)函数,如果函数返回“1”则请客户输入要订的航班号,如果输入的航班号不存在,输出提示信息,如果航班存在则提示客户输入订的票数、客户的姓名和证件号,调用void insert_passengerList(flightnode *&
23、h,passengerList *&PList,char *name,char *ID_num,char *flight_num,int ticket_num)函数,定义航班指针*p=h-next,使用for循环匹配flight_num和p-flight_num,找到后,执行p-left=p-left-ticket_num,修改相应航班的空座数。用malloc函数申请一个客户结点,并用指针*q指向,将客户信息和航班号赋到新申请的结点中,PList-rear-next=q;PList-rear=q;该操作将该结点插入客户链表中。如果该航班已满仓或该航班的空座数不够,输出可供选择的航班,让客户选择
24、,之后调用void insert_passengerList(flightnode *&h,passengerList *&PList,char *name,char *ID_num,char *flight_num,int ticket_num)函数将客户结点插入客户链表中.YN输入航班号,存入flight_num开始flightnode *p=h-next;输入起飞抵达城市,分别存于start_place和end_placeplace_check(h,start_place,end_place)=1N航班号不为空!输入航班号,存入flight_numflight_num=NULLYYNYp
25、!=NULLstrcmp(p-flight_num,flight_num)=0N输入姓名、证件号、订票数,分别存入name、ID_num、ticket_numY航班号不为空!输入航班号,存入flight_numname=NULLN接上页:返回“1”YN证件号不为空!输入证件号,存入ID_numID_num=NULLNN订票数不为空!输入订票数,存入ticket_numticket_num=NULLY调用insert_passengerList函数完成客户订票p-left0&p-left=ticket_numY显示其他可选航班供客户选择调用insert_passengerList函数完成客户订票
26、p=p-next返回“0”结束3.3 顾客退票模块在主函数中输入“3”,调用void cancel(passengerList *&PList,flightnode *&h)函数完成客户的退票。提示客户输入客户的姓名和证件号以及要退的航班号,此函数再调用int delete_passenger(passengerList *&PList,flightnode *&h,char *name,char *ID_num,char *flight_num)函数,用客户结点指针*pr等于已存在客户链表结点Plist的头指针,相当于将*pr指向客户链表的头结点,用客户结点指针*p指向pr的下一个结点。使用
27、while循环寻找匹配姓名、证件号、航班号的客户结点,找到后定义航班指针*f=h-next,使用for循环找到匹配航班号的航班结点,执行f-left=f-left+p-ticket_num,修改退票后相应航班结点的空座数,之后执行pr-next=p-next;free(p);删除要退票的客户订单信息。如果没有找到匹配的客户结点,输出提示信息。开始输入姓名、证件号、航班号,分别存于name、ID_num、flight_num调用delete_passenger函数完成客户的退票结束开始passengernode *pr=PList-headpassengernode *p=pr-nextstrc
28、mp(name,p-name)=0&strcmp(ID_num,p-ID_num)=0&strcmp(flight_num,p-flight_num)=0NY返回“1”返回“0”结束Npr-next=p-nextfree(p)p!=NULLpr=pr-next;p=pr-next;flightnode *f=h-nextf!=NULL!YYNf=f-nextstrcmp(flight_num,f-flight_num)=0Nf-left=f-left+p-ticket_num;Ydelete_passenger函数的流程图:3.4 查询航班模块在主函数中输入“4”,调用void flight_
29、check(flightnode *h)函数选择使用哪一种查询方式进行查询。提示客户输入查询方式,如客户输入“1”,则调用int flight_num_check(flightnode *l,char *flight_num)函数按航班号对航班进行查询,提示客户输入航班号,存于flight_num中;如客户输入“2”,则调用int place_check(flightnode *l,char *start_place,char *end_place)函数按起飞抵达城市对航班进行查询,提示客户输入起飞抵达城市,分别存于start_place和end_place中;如客户输入“3”,则调用void
30、 check_all_flight(flightnode *l)函数浏览全部航班信息。在int flight_num_check(flightnode *l,char *flight_num)函数中,定义航班指针*p=h,使用for循环匹配flight_num和p-flight_num,找到匹配的航班节点后,输出该航班的所有信息。在int place_check(flightnode *l,char *start_place,char *end_place)函数中,定义航班指针*p=h,使用for循环寻找匹配start_place和start_place的结点,找到匹配的航班结点后,输出该航班
31、的所有信息。开始请客户选择查询方式,存于a中根据a的值进行选择a=1a=3a=2调用flight_num_check函数进行查询调用check_all_flight函数进行查询调用place_check函数进行查询结束在void check_all_flight(flightnode *l)函数中,定义航班指针*p=h,使用for循环输出所有航班信息。flight_num_check函数的流程图:YN开始flightnode *p=hp=p-nextp!=NULLstrcmp(p-flight_num,flight_num)=0输出航班信息,返回“1”返回“0”结束NY3.5 查询订单模块在主
32、函数中输入“5”,调用void passenger_check(passengerList *PList)函数选择使用哪一种查询方式进行查询。提示客户输入查询方式,如客户输入“1”,则调用int ID_name_check(passengerList *PList,char *name,char *ID_num)函数按客户的姓名和证件号对订单进行查询,提示客户输入姓名和证件号,分别存于name和ID_num中;如客户输入“2”,则调用int order_num_check(passengerList *PList,int order_num)函数按订单号对订单进行查询,提示客户输入订单号,存于
33、order_num中;如客户输入“3”,则调用void check_all_passenger(passengerList *PList)函数浏览全部订单信息。在int ID_name_check(passengerList *PList,char *name,char *ID_num)函数中,定义客户指针*p= PList-head-next,使用for循环寻找匹配name和ID_num的结点,找到匹配的订单节点后,输出该订单的所有信息。在int order_num_check(passengerList *PList,int order_num)函数中,定义客户指针*p=PList-hea
34、d-next,使用for循环寻找匹配order_num的结点,找到匹配的订单结点后,输出该订单的所有信息。在void check_all_passenger(passengerList *PList)函数中,定义客户指针*p=PList-head-next,使用for循环输出所有订单信息。开始请客户选择查询方式,存于a中根据a的值进行选择a=1a=3a=2调用name_ID_check函数进行查询调用check_all_passenger函数进行查询调用order_num_check函数进行查询结束YN返回“0”输出航班信息,返回“1”结束p=p-nextp!=NULLp-order_num=
35、order_numNY开始passengernode *p=PList-head-nextorder_num_check函数的流程图:3.6 修改航班模块在主函数中输入“6”,调用void modify_flight(flightnode *&h,passengerList *&PList)函数对航班信息进行修改。提示客户输入修改模式,如客户输入“1”,则调用void add_flight(flightnode *&h)函数添加航班信息;如客户输入“2”,则调用void delete_flight(flightnode *&h,passengerList *&PList)函数删除指定的航班信息
36、,提示客户输入航班号,存于flight_num中;如客户输入“3”,则示客户输入航班号,如果该航班号存在,则提示用户输入修改后的起飞抵达时间。开始请客户选择修改模式,存于a中根据a的值进行选择a=1a=3a=2调用add_flight函数添加航班信息输入航班号,存入flight_num调用delete_flight函数删除航班结束flight_num_check(p,flight_num)=1输入修改后的起飞抵达时间,分别存入start_time和end_timeflightnode *p=h-nextstrcmp(flight_num,p-flight_num)=0p!=NULLstrcpy
37、(p-start_time,start_time)strcpy(p-end_time,end_time)p=p-next在void delete_flight(flightnode *&h,passengerList *&PList)函数中,定义航班指针*pr=h,定义航班指针p=pr-next,定义客户指针*qr=PList-head,定义客户指针*q=qr-next。使用while循环寻找匹配航班号的航班结点,找到后执行pr-next=p-next;free(p),删除指定的航班信息;使用while循环找到匹配航班号的订单结点,执行qr-next=q-next;free(q),删除对该航班
38、订票的订单信息。如果没有找到匹配的航班结点,输出提示信息。4. 测试与分析4.1 合法数据的测试(1) 编译链接后显示菜单(2) 输入菜单号“1”,开始航班信息的录入(3) 输入菜单号“2”,进入订票模块(4) 输入菜单号“3”,进入退票模块(5) 输入菜单号“4”,查询航班信息a. 输入菜单号“1”,按航班号查询航班信息b. 输入菜单号“2”,按起飞抵达城市查询航班信息c. 输入菜单号“3”,浏览全部航班信息(6) 输入菜单号“5”,查询订单信息a. 输入菜单号“1”,按客户姓名和证件号查询订单信息b. 输入菜单号“2”,按订单号查询订单信息c. 输入菜单号“3”,浏览全部订单信息(7) 输
39、入菜单号“6”,进入航班修改模块a. 输入菜单号“1”,增加航班b. 输入菜单号“2”,删除航班c. 输入菜单号“3”,修改航班时间(8) 输入菜单号“0”,退出本系统。4.2 非法数据的测试(1) 在主菜单中输入错误号码后,系统自动跳转到主菜单,继续让用户输入。(2) 选择订票服务后,输入了没有开通航班的城市(3) 选择订票服务后,输入了系统中没有的航班号(4) 选择退票服务后,输入了没有订票的客户姓名和证件号(5) 选择航班查询服务后,输入了没有开通航班的城市(6) 选择航班查询服务后,输入了系统中不存在的航班号(7) 选择订单查询服务后,输入了没有订票的客户姓名和证件号(8) 选择订单查
40、询服务后,输入了系统中不存在的订单号(9) 选择删除航班服务后,输入了系统中不存在的航班号(10) 选择修改航班时间服务后,输入了系统中不存在的航班号5. 用户使用说明5.1 运行环境Windows xp;Microsoft Visual C+ 6.05.2 主要功能飞机订票系统系统功能模块如下:主要功能包括录入航班信息、客户订票、客户退票、查询航班信息、查询订单信息、修改航班信息六个模块;其中查询航班信息模块包括按航班号查询、按起飞抵达城市查询和浏览全部航班信息;其中查询订单信息模块包括按订单号查询、按客户姓名和证件号查询以及浏览全部订单信息;其中修改航班信息模块包括添加航班信息、删除航班信
41、息和修改航班起飞抵达时间。5.3 操作注意事项用户在使用飞机订票系统之前,应注意以下事项:用户在输入数据时,飞机航班号、起飞抵达城市、起飞抵达时间、客户姓名、证件号等为字符串形式;空座数、订票数量、航班是否满仓等为整型(int);票价、票价折扣等为浮点型(float);其他形式的输入,请按输入提示进行操作,以免引起不必要的故障。5.4 业务流程输入相应的选择信息,便可进入相应的模块中。(1)输入“1”,进入【录入航班信息】模块,输入航班的相关信息,完成航班信息的录入。(2)输入“2”,进入【客户订票】模块,输入客户的信息、要订的票数和要订的航班号,完成客户的订票操作。(3)输入“3”,进入【客
42、户退票】模块,输入客户的信息、要退的航班号,完成客户的退票操作。(4)输入“4”,进入【查询航班信息】模块,可以浏览或查询航班的相关信息。(5)输入“5”,进入【查询订单信息】模块,可以浏览或查询订单的相关信息。(6)输入“6”,进入【修改航班信息】模块,可以添加航班信息、删除航班信息和修改航班的起飞抵达时间。6. 总结经过这两周的数据结构课程设计,我收获很大,在实现系统功能的过程中,也遇到很多问题,分工协作,设计修改,编写调试,每一步都渗透着沟通和分析,每一次沟通之后,都会对系统功能有更深层次的理解和阐述,这也促使我们一步步完成了整个系统,并使之可以运行。两周的时间太短暂了,我们无法把全部学
43、到的知识运用到具体的系统实现中,深深感受到数据结构这门课程的重要性,以及它在实际应用中的广泛性。本系统由于种种原因仍然存在需要改进,需要完善的地方,我对于这个系统的认识和对数据结构这门课程的理解已经更加深入了。在今后的学习和工作中,会更加深入地把知识和思想体会更广泛地应用到其他相关领域。本系统在人性化的方面做得还不够,对于另类的输入错误,还不能很好地应对,这也体现出本系统不够健壮,会在今后的学习中加以改进和完善;在功能模块方面还可以增加更多相关模块,是系统更加完善。在实现系统的过程中,我感受到自己的知识的薄弱零散,经过这次做系统,我觉得自己的知识得到巩固和整合,知识体系更加系统化。我也深深体会到实践检验真理,只有实践中,才能出真知。我懂得了学习不只是纸上谈兵,更重要的是实践,就比如平常我们在学习中经常会遇到一些问题,看似无关紧要跳过去,不求甚解,在得知答案的时候,总是感觉心领神会,久而久之,对于的知识点就模棱两可,形成知识漏洞。但这次课程设计所要编写的程序很长,涉及的知识点也很多,选择此题目的时候我心里面还底气十足,自认为没什么问题,对于程序的步骤仿佛了然于胸,但在实际操作中才发现并非如此,在编写程序的过程中,我不断地查阅相关资料进行学习,积极地思考该怎样实现系统的每一个功能。通过这次