C语言如何实现飞机订票系统
这篇文章将为大家详细讲解有关C语言如何实现飞机订票系统,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
问题描述与题目要求
问题描述: 假定某民航有M个航次的班机,每个航次都只到达一个地方。试为该机场售票处设计一个自动订票和退票系统,要求系统具有以下功能:(1)订票:若该航次余票大于等于乘客订票数,则在该航次的乘客表中,插入订票乘客的信息项,并修改该航次有关数据,否则给出相应信息。(2)退票:若该航次当前退票数小于等于乘客原订票数,则在相应的乘客表中找到该乘客项,修改该航次及乘客表中有关数据;当某乘客由于退票使订票数为零时,则从乘客表中撤消该数据项。
要求:
(1)描述对航次表和乘客表选用的数据结构。(2)编程实现飞机票订票和退票系统。
模型假设
1.假设所有输入均为整数且在int类型的表示范围内2.假设航次是从1到n的连续整数3.假设每个乘客 ID 均唯一
数据结构的选用
联想到图中的邻接链表,采用相似的数据结构描述该问题航次表: 用一个数组flight_info_list存储每个航次的乘客表,该数组下标即为航班航次,对应元素即为该航次相关信息(乘客表,航班编号及航班余票数)乘客表: 用双向链表存储每个航次的乘客表passenger_info_list,每个结点存储乘客的 ID,订票数以及指向前、后结点的指针
编程实现(C语言实现)
/* *@Description:模拟航班的订票系统 *模型假设: *1.飞机最大载客量为300人 *2.共10个航次 *用双向链表存储乘客信息 *用array存储航班信息 *@Author:Fishermanykx *@Date:2019-09-2910:32:56 *@LastEditors:Fishermanykx *@LastEditTime:2019-09-3012:29:16 */ #include<stdbool.h> #include<stdio.h> #include<stdlib.h> #defineMAX_CAPACITY300//假定飞机最大载客量为300 #defineTOTAL_AIRLINE10//假定不同航线最大数目为10 #defineBOOK_TICKET1 #defineREFUND-1 #defineEXIT_SYSTEM0 #definePRINT_INFO11 #defineROOT123456 //某航次航班 structSingleFlight{ intflight_id;//航班编号,从1开始,到TOTAL_AIRLINE为止 intremain_tickets;//该航班余票数 structSinglePassenger*passenger_info_list;//该航班乘客表 }; //某航次航班的某个乘客的信息 structPassengerInfo{ intpassenger_id;//乘客id intticket_number;//该乘客购买票数 }; //乘客表中的一个结点 structSinglePassenger{ structPassengerInfopassenger_info;//乘客信息 structSinglePassenger*prev_passenger;//指向前一个乘客的指针 structSinglePassenger*next_passenger;//指向后一个乘客的指针 }; typedefstructSingleFlightSingleFlight; typedefstructSinglePassengerSinglePassenger; //订票操作 SingleFlight*BookTicket(SingleFlightflight_info_list[]); SinglePassenger*GetNewPassenger(constintnew_passenger_id, constintbook_ticket_number); SinglePassenger*AddNewPassenger(SinglePassenger*head, constintnew_passenger_id, constintbook_ticket_number); //退票操作 SingleFlight*Refund(SingleFlightflight_info_list[]); SinglePassenger*RemovePassenger(SinglePassenger*head,constintpassenger_id); //判断操作 boolIsPassengerExist(SinglePassenger*head,constintpassenger_id); //打印操作 voidPrintCurrentAirlineInfo(SingleFlightflight_info_list[]); voidPrintPassengerList(SinglePassenger*head,SingleFlight*flight_info_list, intairline_id); intmain(void){ intorder,exit_loop=1; //初始化航班信息 SingleFlight*flight_info_list; flight_info_list= (SingleFlight*)malloc(TOTAL_AIRLINE*sizeof(SingleFlight)); for(inti=0;i<TOTAL_AIRLINE;++i){ flight_info_list[i].flight_id=i+1; flight_info_list[i].remain_tickets=MAX_CAPACITY; flight_info_list[i].passenger_info_list=NULL; } /*登录界面*/ printf("您好,欢迎使用此系统!\n\n"); printf("使用说明:\n"); printf("1.本程序所有输入均为整数\n"); printf("2.可供选择的航次编号为1-%d,每架次最大载客量为%d\n",TOTAL_AIRLINE, MAX_CAPACITY); printf( "3.若订票,请输入1;若退票,请输入-1;若退出系统,请输入0;" "若要以root用户登录,请输入root密码\n"); printf("使用说明到此结束,祝您使用愉快!\n"); //判断是否以root登录 intlog_in_as_root,root_key; boolis_root=false; printf("-------------------------------------------------------------\n\n"); printf("是否以root用户登录?若是,请输入1,否则请输入0:"); scanf("%d",&log_in_as_root); if(log_in_as_root)printf("请输入root密码(按0退出root登录程序):"); while(log_in_as_root){ scanf("%d",&root_key); if(!root_key){ break; }elseif(root_key!=ROOT){ printf("输入密码错误!请重新输入或按0退出root登录程序:"); }else{ is_root=true; break; } } //欢迎界面 if(is_root) printf("欢迎,root用户!输入11可查看当前航次表\n"); else printf("欢迎,普通用户!\n"); printf("-------------------------------------------------------------\n"); //主循环 while(true){ if(is_root) printf("请输入1,0,-1或11中的一个数字:"); else printf("请输入1,0,-1中的一个数字:"); scanf("%d",&order); switch(order){ caseBOOK_TICKET: flight_info_list=BookTicket(flight_info_list); break; caseREFUND: flight_info_list=Refund(flight_info_list); break; caseEXIT_SYSTEM: exit_loop=0; break; casePRINT_INFO: printf( "-------------------------------------------------------------\n"); PrintCurrentAirlineInfo(flight_info_list); break; default: printf("非法输入!\n"); break; } if(!exit_loop)break; } return0; } /** *@description:一次订票操作的模拟 *@param{type} *flight_info_list{SingleFlight*}:航班信息表(航次表) *@return: */ SingleFlight*BookTicket(SingleFlightflight_info_list[]){ /*获取乘客预定航次*/ inttarget_airline; printf("可供选择的航次对应的编号为:1-%d\n",TOTAL_AIRLINE); printf("请输入您想预定的航次(输入0时退出订票程序):"); //判断输入合法性 while(true){ scanf("%d",&target_airline); if(target_airline<0||target_airline>TOTAL_AIRLINE){ printf("您要预定的航次不存在!\n"); printf("请重新输入一个正确的航次,或按0退出订票程序:"); }elseif(target_airline==0){ printf("-------------------------------------------------------------\n"); returnflight_info_list; }else break; } /*获取乘客id*/ intpassenger_id; intmodify_tickets; printf("若您原先已经订票,且想增加您的订票数,请输入1,否则请输入0:"); //判断输入合法性 while(true){ scanf("%d",&modify_tickets); if(modify_tickets!=1&&modify_tickets!=0){ printf("您输入的是非法命令,请重新输入0(原先未订票)或1(原先已经订票):"); }else break; } printf("请输入您的ID:"); //若原先未订票 while(!modify_tickets){ scanf("%d",&passenger_id); if(IsPassengerExist( flight_info_list[target_airline-1].passenger_info_list, passenger_id)){ printf("该ID已存在,请输入一个新的ID:"); }else break; } //若原先已经订票 if(modify_tickets){ scanf("%d",&passenger_id); if(!IsPassengerExist( flight_info_list[target_airline-1].passenger_info_list, passenger_id)){ printf("您原先并未预订该航次的票!\n"); printf("-------------------------------------------------------------\n"); returnflight_info_list; } } /*获取乘客预定票数*/ //获取当前航次余票数 intremain_tickets; remain_tickets=flight_info_list[target_airline-1].remain_tickets; printf("当前航次余票数为:%d\n",remain_tickets); //若该乘客想修改票数,显示此乘客此前预订的票数 if(modify_tickets){ SinglePassenger*head= flight_info_list[target_airline-1].passenger_info_list; while(head->passenger_info.passenger_id!=passenger_id){ head=head->next_passenger; } printf("您此前预订的票数为%d张\n",head->passenger_info.ticket_number); } //获取乘客想预定的票数 inttarget_ticket_num; printf("请输入您想预定(或增订)的票数:"); //判断输入合法性 while(true){ scanf("%d",&target_ticket_num); if(target_ticket_num>remain_tickets){ printf("您想预定的票数为%d,但当前航次余票数仅为%d,余票不足!\n", target_ticket_num,remain_tickets); printf("请输入您想预定的票数,或按0退出订票程序:"); }elseif(target_ticket_num==0){ printf("-------------------------------------------------------------\n"); returnflight_info_list; }else{ break; } } /*修改航次余票数*/ flight_info_list[target_airline-1].remain_tickets-=target_ticket_num; /*修改乘客表中对应的项*/ //判断该乘客原先是否存在 if(modify_tickets){ //若存在,找到该乘客并修改他的订票项 SinglePassenger*tmp= flight_info_list[target_airline-1].passenger_info_list; while(tmp->passenger_info.passenger_id!=passenger_id){ tmp=tmp->next_passenger; } tmp->passenger_info.ticket_number+=target_ticket_num; printf("增订成功!您现在共预订%d张航次%d的票\n", tmp->passenger_info.ticket_number,target_airline); }else{ //若不存在,则在该航次的乘客列表中增加该乘客及其对应信息 flight_info_list[target_airline-1].passenger_info_list=AddNewPassenger( flight_info_list[target_airline-1].passenger_info_list,passenger_id, target_ticket_num); printf("预订成功!您现在共预订%d张航次%d的票\n",target_ticket_num, target_airline); } printf("-------------------------------------------------------------\n"); returnflight_info_list; } /** *@description:查找乘客表(双向链表)中某乘客是否存在 *@param{type} *head{SinglePassenger*}:双向链表头结点 *passenger_id{constint}:待查找的键值 *@return:若存在,返回true;否则返回false */ boolIsPassengerExist(SinglePassenger*head,constintpassenger_id){ SinglePassenger*tmp=head; boolexist=false; if(!head){ returnfalse; } while(tmp){ if(tmp->passenger_info.passenger_id==passenger_id){ exist=true; break; } tmp=tmp->next_passenger; } returnexist; } /** *@description:初始化一个新结点 *@param{type} *new_passenger_id{constint}:新增加的乘客的id *book_ticket_number{constint}:新增加乘客的订票数 *@return:初始化后的结点(前驱,后继均为空指针) */ SinglePassenger*GetNewPassenger(constintnew_passenger_id, constintbook_ticket_number){ SinglePassenger*new_passenger= (SinglePassenger*)malloc(sizeof(SinglePassenger)); new_passenger->passenger_info.passenger_id=new_passenger_id; new_passenger->passenger_info.ticket_number=book_ticket_number; new_passenger->next_passenger=NULL; new_passenger->prev_passenger=NULL; returnnew_passenger; } SinglePassenger*AddNewPassenger(SinglePassenger*head, constintnew_passenger_id, constintbook_ticket_number){ SinglePassenger*new_passenger= GetNewPassenger(new_passenger_id,book_ticket_number); if(!head){ head=new_passenger; }else{ //直接从头部插入 new_passenger->next_passenger=head->next_passenger; if(head->next_passenger){ head->next_passenger->prev_passenger=new_passenger; } new_passenger->prev_passenger=head; head->next_passenger=new_passenger; } returnhead; } /** *@description:一次退票操作的模拟 *@param{type} *flight_info_list{SingleFlight*}:航次表 *@return:修改后的航次表 */ SingleFlight*Refund(SingleFlightflight_info_list[]){ /*获取乘客预定航次*/ inttarget_airline; printf("可供选择的航次对应的编号为:1-%d\n",TOTAL_AIRLINE); printf("请输入您想退订的航次(输入0时退出订票程序):"); //判断输入合法性 while(true){ scanf("%d",&target_airline); if(target_airline<0||target_airline>TOTAL_AIRLINE){ printf("您要退订的航次不存在!\n"); printf("请重新输入一个正确的航次,或按0退出退票程序:"); }elseif(target_airline==0){ printf("-------------------------------------------------------------\n"); returnflight_info_list; }else break; } /*获取乘客ID并判断其合法性*/ intpassenger_id; printf("请输入您的ID:"); scanf("%d",&passenger_id); SinglePassenger*head= flight_info_list[target_airline-1].passenger_info_list; if(!IsPassengerExist(head,passenger_id)){ printf("您并未预订此次航班!\n"); printf("-------------------------------------------------------------\n"); returnflight_info_list; } /*获取乘客退票数*/ //打印此乘客的预订票数 SinglePassenger*tmp=head; while(tmp->passenger_info.passenger_id!=passenger_id){ tmp=tmp->next_passenger; } printf("您当前预订的票数为:%d张\n",tmp->passenger_info.ticket_number); //读入退票数 intrefund_ticket_num; printf("请输入您的退票数(输入0退出退票程序):"); scanf("%d",&refund_ticket_num); //输入合法性检查 intcur_ticket=tmp->passenger_info.ticket_number;//当前该乘客预订的票数 while(cur_ticket<refund_ticket_num){ if(!refund_ticket_num){ printf("-------------------------------------------------------------\n"); returnflight_info_list; } printf("您输入的退票数大于您当前预订的票数!"); printf("请重新输入退票数(输入0退出退票程序):"); scanf("%d",&refund_ticket_num); } /*退票*/ //更新航次表 flight_info_list[target_airline-1].remain_tickets+=refund_ticket_num; //更新乘客表 if(cur_ticket>refund_ticket_num){ tmp->passenger_info.ticket_number-=refund_ticket_num; printf("您已成功退票,现在您%d航次的余票为%d张\n",target_airline, tmp->passenger_info.ticket_number); }else{ flight_info_list[target_airline-1].passenger_info_list= RemovePassenger(head,passenger_id); printf("您已成功退票,现在您%d航次的余票为%d张\n",target_airline,0); } printf("-------------------------------------------------------------\n"); returnflight_info_list; } /** *@description:从乘客表中删除某个结点 *@param{type} *head{SinglePassenger*}:乘客表 *passenger_id{constint}:待删除乘客的id *@return:修改后的航次表 */ SinglePassenger*RemovePassenger(SinglePassenger*head, constintpassenger_id){ SinglePassenger*tmp=head; while(tmp->passenger_info.passenger_id!=passenger_id){ tmp=tmp->next_passenger; } //若为头结点 if(!tmp->prev_passenger){ head=head->next_passenger; } //若为尾结点 elseif(!tmp->next_passenger){ tmp->prev_passenger->next_passenger=NULL; } //若为中间某个结点 else{ tmp->prev_passenger->next_passenger=tmp->next_passenger; tmp->next_passenger->prev_passenger=tmp->prev_passenger; } returnhead; } /** *@description:输出当前航次表 *@param{type} *flight_info_list{SingleFlight*}:航班信息表(航次表) *@return:void */ voidPrintCurrentAirlineInfo(SingleFlightflight_info_list[]){ for(intcurrent_airline_index=1;current_airline_index<=TOTAL_AIRLINE; ++current_airline_index){ intremain_ticket_num= flight_info_list[current_airline_index-1].remain_tickets; SinglePassenger*head= flight_info_list[current_airline_index-1].passenger_info_list; //输出 PrintPassengerList(head,flight_info_list,current_airline_index); printf("-------------------------------------------------------------\n"); } } /** *@description:打印某航次的乘客表 *@param{type} *head{SinglePassenger*}:乘客表的头结点 *flight_info_list{SingleFlight*}:航次表 *@return: */ voidPrintPassengerList(SinglePassenger*head,SingleFlight*flight_info_list, intairline_id){ if(!head){ printf("%d航次无乘客订票!\n",airline_id); }else{ printf("%d航次余票数为:%d,其中:\n",airline_id, flight_info_list[airline_id-1].remain_tickets); } while(head){ printf("ID为%d的乘客订票数为%d张\n",head->passenger_info.passenger_id, head->passenger_info.ticket_number); head=head->next_passenger; } printf("\n"); }
实现亮点
1.每一步操作均有对非法输入的处理,最大限度上确保了程序运行的稳定性2.区分root用户和普通用户,且只有root用户能够查看所有人的订票情况,从而保护了客户的隐私3.使用双向链表存储乘客信息,一方面便于存取乘客的信息(定长数组分配的是栈内存,而栈内存小于堆内存,所以用链表进行存储更不容易造成内存溢出),另一方面降低了编程难度(既不需要实现对数组进行动态内存分配的一系列操作,又最大限度地降低了删除结点操作的复杂度)
实现缺点
1.只考虑了数字输入的情况,没有考虑字符及其他数据类型的输入2.用链表存储导致不能随机访问,使查找操作复杂度始终为O(n) O(n)O(n)
运行结果
您好,欢迎使用此系统! 使用说明: 1.本程序所有输入均为整数 2.可供选择的航次编号为1-10,每架次最大载客量为300 3.若订票,请输入1;若退票,请输入-1;若退出系统,请输入0;若要以root用户登录,请输入root密码 使用说明到此结束,祝您使用愉快! ------------------------------------------------------------- 是否以root用户登录?若是,请输入1,否则请输入0:1 请输入root密码(按0退出root登录程序):123456 欢迎,root用户!输入11可查看当前航次表 ------------------------------------------------------------- 请输入1,0,-1或11中的一个数字:1 可供选择的航次对应的编号为:1-10 请输入您想预定的航次(输入0时退出订票程序):1 若您原先已经订票,且想增加您的订票数,请输入1,否则请输入0:0 请输入您的ID:1 当前航次余票数为:300 请输入您想预定(或增订)的票数:12 预订成功!您现在共预订12张航次1的票 ------------------------------------------------------------- 请输入1,0,-1或11中的一个数字:1 可供选择的航次对应的编号为:1-10 请输入您想预定的航次(输入0时退出订票程序):1 若您原先已经订票,且想增加您的订票数,请输入1,否则请输入0:0 请输入您的ID:2 当前航次余票数为:288 请输入您想预定(或增订)的票数:21 预订成功!您现在共预订21张航次1的票 ------------------------------------------------------------- 请输入1,0,-1或11中的一个数字:1 可供选择的航次对应的编号为:1-10 请输入您想预定的航次(输入0时退出订票程序):1 若您原先已经订票,且想增加您的订票数,请输入1,否则请输入0:0 请输入您的ID:3 当前航次余票数为:267 请输入您想预定(或增订)的票数:32 预订成功!您现在共预订32张航次1的票 ------------------------------------------------------------- 请输入1,0,-1或11中的一个数字:1 可供选择的航次对应的编号为:1-10 请输入您想预定的航次(输入0时退出订票程序):2 若您原先已经订票,且想增加您的订票数,请输入1,否则请输入0:0 请输入您的ID:32 当前航次余票数为:300 请输入您想预定(或增订)的票数:2 预订成功!您现在共预订2张航次2的票 ------------------------------------------------------------- 请输入1,0,-1或11中的一个数字:1 可供选择的航次对应的编号为:1-10 请输入您想预定的航次(输入0时退出订票程序):10 若您原先已经订票,且想增加您的订票数,请输入1,否则请输入0:0 请输入您的ID:212 当前航次余票数为:300 请输入您想预定(或增订)的票数:123 预订成功!您现在共预订123张航次10的票 ------------------------------------------------------------- 请输入1,0,-1或11中的一个数字:1 可供选择的航次对应的编号为:1-10 请输入您想预定的航次(输入0时退出订票程序):1 若您原先已经订票,且想增加您的订票数,请输入1,否则请输入0:1 请输入您的ID:1 当前航次余票数为:235 您此前预订的票数为12张 请输入您想预定(或增订)的票数:-1 增订成功!您现在共预订11张航次1的票 ------------------------------------------------------------- 请输入1,0,-1或11中的一个数字:-1 可供选择的航次对应的编号为:1-10 请输入您想退订的航次(输入0时退出订票程序):1 请输入您的ID:2 您当前预订的票数为:21张 请输入您的退票数(输入0退出退票程序):222 您输入的退票数大于您当前预订的票数!请重新输入退票数(输入0退出退票程序):2 您已成功退票,现在您1航次的余票为19张 ------------------------------------------------------------- 请输入1,0,-1或11中的一个数字:1 可供选择的航次对应的编号为:1-10 请输入您想预定的航次(输入0时退出订票程序):10 若您原先已经订票,且想增加您的订票数,请输入1,否则请输入0:32 您输入的是非法命令,请重新输入0(原先未订票)或1(原先已经订票):0 请输入您的ID:322 当前航次余票数为:177 请输入您想预定(或增订)的票数:12 预订成功!您现在共预订12张航次10的票 ------------------------------------------------------------- 请输入1,0,-1或11中的一个数字:-1 可供选择的航次对应的编号为:1-10 请输入您想退订的航次(输入0时退出订票程序):10 请输入您的ID:212 您当前预订的票数为:123张 请输入您的退票数(输入0退出退票程序):123 您已成功退票,现在您10航次的余票为0张 ------------------------------------------------------------- 请输入1,0,-1或11中的一个数字:11 ------------------------------------------------------------- 1航次余票数为:238,其中: ID为1的乘客订票数为11张 ID为3的乘客订票数为32张 ID为2的乘客订票数为19张 ------------------------------------------------------------- 2航次余票数为:298,其中: ID为32的乘客订票数为2张 ------------------------------------------------------------- 3航次无乘客订票! ------------------------------------------------------------- 4航次无乘客订票! ------------------------------------------------------------- 5航次无乘客订票! ------------------------------------------------------------- 6航次无乘客订票! ------------------------------------------------------------- 7航次无乘客订票! ------------------------------------------------------------- 8航次无乘客订票! ------------------------------------------------------------- 9航次无乘客订票! ------------------------------------------------------------- 10航次余票数为:288,其中: ID为322的乘客订票数为12张 ------------------------------------------------------------- 请输入1,0,-1或11中的一个数字:0
注:普通用户不能执行查看所有乘客信息的操作,只能查看自己的购票信息
关于“C语言如何实现飞机订票系统”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
推荐阅读
windows安装touble c
近期有些网友想要了解windows?安装touble的相关情况,小编通过整理给您分享一下。为什么现在还需要TurboC?在当今V...
C/C++如何获取CAN信号
C/C++如何获取CAN信号本篇内容主要讲解“C/C++如何获取C...
C语言怎么通过二分查找实现猜数字游戏
C语言怎么通过二分查找实现猜数字游戏本文小编为大家详细介绍“C语言...
C语言数据结构中的线性表怎么使用
C语言数据结构中的线性表怎么使用这篇文章主要介绍“C语言数据结构中...
C语言的数据结构怎么理解
C语言的数据结构怎么理解这篇文章主要介绍了C语言的数据结构怎么理解...
C语言与C++中内存管理的方法
C语言与C++中内存管理的方法这篇文章主要介绍了C语言与C++中内...
C语言链式队列与循环队列怎么实现
C语言链式队列与循环队列怎么实现这篇文章主要介绍了C语言链式队列与...
C语言冒泡排序怎么实现
C语言冒泡排序怎么实现这篇文章主要介绍了C语言冒泡排序怎么实现的相...
C语言如何实现斐波那契数列
C语言如何实现斐波那契数列这篇文章主要介绍了C语言如何实现斐波那契...
C语言如何实现无符号数和有符号数间的运算
C语言如何实现无符号数和有符号数间的运算本篇内容主要讲解“C语言如...