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语言如何实现飞机订票系统”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

发布于 2021-05-30 14:07:47
分享
海报
170
上一篇:C语言如何实现旅游景点咨询系统下一篇:C语言如何实现简单航班管理系统
目录

    忘记密码?

    图形验证码