目录
前言
一、作业要求介绍
二、各个函数的实现
1.头文件总结需要的功能
(1)结构体的定义
(2)各个功能的函数
2.各个函数的具体实现
(1)初始化
(2)打印航班信息表
(4)查找航班信息
(5)订票系统
(6)退票信息
(7)保存本地文件
(8)七七八八的菜单
三.程序的运行
总结
文章来源地址https://www.toymoban.com/news/detail-769403.html
文章来源:https://www.toymoban.com/news/detail-769403.html
前言
本题的来源是数据结构期末作业。把作业写成博客是为了重新梳理一遍思路,也是向组员解释一下各个函数的功能。
一、作业要求介绍
总结一下 基本上就是以下几点
(1) 手动添加航线信息
(2)通过终点站名搜索航线
(3)输入航班号 可以订票,如果航班人没满 则将其放入乘客席中,如果这个航班人满了 要有候补席
(4)可以通过航班号和名字退票 并将候补席中第一个合适的人选 放入购票席中
(5)最后将文件保存本地 下次使用也要保存信息
二、各个函数的实现
1.头文件总结需要的功能
(1)结构体的定义
① 舱位
ps:
这里舱位级别是用枚举常量定义的
主要目的就是为了防止方便看代码
候补席的人 舱位统一为 No
//舱位级别
enum Class_Of_Travel
{
No,//没买呢
One,//一等
Two,//二等
Three//三等
};//舱位级别
② 乘客个人信息
//乘客个人信息
typedef struct Pasger
{
char Name[20];//姓名
int Amount;//购票量
enum Class_Of_Travel Class;//舱位等级
}Pasger_Type;//乘客个人信息
③ 乘客席信息
为了方便乘客退票时的信息删除 这里用链式存储
//乘客席信息
typedef struct SList_For_Bought
{
Pasger_Type data;
SList_For_Bought* next;
}Bought_Type;//乘客席信息
④ 候补席信息
因为这里并不是完全的先进先出 所以是没必要用队列的
但我一开始用的是队列 后面就没有改了
//候补席信息
typedef struct Queue_For_WantBuy
{
Pasger_Type* data;
int front;
int rear;
}WantBuy_Type;//候补席信息
⑤ 航线信息
//航线信息
typedef struct Route_Info
{
char Terminal[20];//终点站
char Route_Name[20];//航班号
char Plane_Name[20];//飞机号
char Fly_Week[20];//周几飞
int bought_number;//购票人数
int Pasger_Max;//最大客容量
int Surplus;//剩余票量
Bought_Type* Bought;//已购票
WantBuy_Type* WantBuy;//替补购票
}Route_Info_Type;//航线信息
⑥ 航班表
//航班表
typedef struct SeqList_For_Route
{
Route_Info_Type* Route;
int size;
int capacity;
}Routes_List_Type;//航班表
(2)各个功能的函数
//初始化航班表
void PS_Init(Routes_List_Type* RL);
//查看所有航班信息
void PS_Print(Routes_List_Type* RL);
//增加航班信息
void PS_Push(Routes_List_Type* RL);
//查找航班信息
void PS_Search(Routes_List_Type* RL);
//订票功能
void PS_BuyTicket(Routes_List_Type* RL);
//退票功能
void PS_ReturnTicket(Routes_List_Type* RL);
//保存航班表
void PS_Save(Routes_List_Type* RL);
2.各个函数的具体实现
(1)初始化
初始化分为两部分
一部分负责初始化航班信息的顺序表
//初始化(1)
void PS_Init(Routes_List_Type* RL)
{
RL->Route = (Route_Info_Type*)malloc(sizeof(Route_Info_Type) * PS_MAX);
if (RL->Route == NULL)
{
printf("PS_Init malloc");
exit(-1);
}
RL->size = 0;
RL->capacity = PS_MAX;
}
一部分负责导入本地文件
这部分的顺序和Save的储存顺序一样就行了
需要注意的是 不能只存 RL航空信息顺序表
还需要特别注意 乘客席的链表 和 候补席的队列 也需要独立的代码去存储
//初始化(2)
void PS_Init(Routes_List_Type* RL)
{
//导入本地文件信息
FILE* pf = fopen("Plane_System.dat", "rb");
if (pf == NULL)
{
return;
}
Route_Info_Type* tmp = (Route_Info_Type*)malloc(sizeof(Route_Info_Type));
while (fread(tmp, sizeof(Route_Info_Type), 1, pf))
{
int bought = tmp->Pasger_Max - tmp->Surplus;//购票人数
tmp->Bought = (Bought_Type*)malloc(sizeof(Bought_Type));
Bought_Type* tmp1 = tmp->Bought;
for (int i = 0; i < tmp->bought_number; i++)
{
fread(tmp1, sizeof(Bought_Type), 1, pf);
tmp1->next = (Bought_Type*)malloc(sizeof(Bought_Type));
if (i != tmp->bought_number - 1)
tmp1 = tmp1->next;
else
tmp1->next = NULL;
}
tmp->WantBuy = (WantBuy_Type*)malloc(sizeof(WantBuy_Type));
fread(&tmp->WantBuy->front, sizeof(int), 1, pf);
fread(&tmp->WantBuy->rear, sizeof(int), 1, pf);
tmp->WantBuy->data = (Pasger_Type*)malloc(sizeof(Pasger_Type) * 100);
fread(tmp->WantBuy->data, sizeof(Pasger_Type), tmp->WantBuy->rear, pf);
PS_Check(RL);
RL->Route[RL->size] = *tmp;
RL->size++;
}
fclose(pf);
pf = NULL;
}
(2)打印航班信息表
这个不重要
//显示所有航班信息
void PS_Print(Routes_List_Type* RL)
{
system("cls");
printf("航班信息总表如下:\n\n");
for (int i = 0; i < RL->size; i++)
{
printf("终点站为: %s\n", RL->Route[i].Terminal);
printf("航班号为: %s\n", RL->Route[i].Route_Name);
printf("飞机号为: %s\n", RL->Route[i].Plane_Name);
printf("飞行时间: %s\n", RL->Route[i].Fly_Week);
printf("剩余票量: %d\n", RL->Route[i].Surplus);
printf("候补人数: %d\n", RL->Route[i].WantBuy->rear- RL->Route[i].WantBuy->front);
printf("\n");
}
system("pause");
}
(3)增加航班信息
就是链表 队列的综合运用 就是看起来比较长
void PS_Push(Routes_List_Type* RL)//加入航班信息
{
system("cls");
PS_Check(RL);
//终点站
printf("请输入终点站:\n");
scanf("%s",RL->Route[RL->size].Terminal);
//航班号
printf("请输入航班号:\n");
scanf("%s",RL->Route[RL->size].Route_Name);
//飞机号
printf("请输入飞机号:\n");
scanf("%s",RL->Route[RL->size].Plane_Name);
//周几起飞
printf("请输入周几起飞:\n");
scanf("%s",RL->Route[RL->size].Fly_Week);
//最大客容量
printf("请输入最大客容量:\n");
scanf("%d",&RL->Route[RL->size].Pasger_Max);
printf("请输入有现有几人购票:\n");
scanf("%d", &RL->Route[RL->size].bought_number);
RL->Route[RL->size].Bought = (Bought_Type*)malloc(sizeof(Bought_Type));
int sold = 0;//已售出的数量
int flag = 0;//判断是否只有一个人买票
if (RL->Route[RL->size].bought_number)
{
printf("请输入第1名乘客买几张票 共有%d人\n", RL->Route[RL->size].bought_number);
scanf("%d", &RL->Route[RL->size].Bought->data.Amount);
sold += RL->Route[RL->size].Bought->data.Amount;
printf("请输入第1名乘客舱位级别(1,2,3)\n");
scanf("%d", &RL->Route[RL->size].Bought->data.Class);
printf("请输入第1名乘客叫什么\n");
scanf("%s", RL->Route[RL->size].Bought->data.Name);
RL->Route[RL->size].Bought->next = (Bought_Type*)malloc(sizeof(Bought_Type));
Bought_Type* cur = RL->Route[RL->size].Bought->next;
for (int i = 0; i < RL->Route[RL->size].bought_number - 1; i++)
{
printf("请输入第%d名乘客买几张票 共有%d人\n", i + 2, RL->Route[RL->size].bought_number);
scanf("%d", &(cur->data.Amount));
sold += cur->data.Amount;
printf("请输入第%d名乘客舱位级别(1,2,3)\n", i + 2);
scanf("%d", &(cur->data.Class));
printf("请输入第%d名乘客叫什么\n", i + 2);
scanf("%s", cur->data.Name);
if (i != RL->Route[RL->size].bought_number - 2)//从第一次到倒数第二次循环
{
cur->next = (Bought_Type*)malloc(sizeof(Bought_Type));
cur = cur->next;
}
if (i == RL->Route[RL->size].bought_number - 2)
{
cur->next = NULL;
flag = 1;
}
}
if (flag == 0)
RL->Route[RL->size].Bought->next = NULL;
}
else
printf("无人购票\n");
RL->Route[RL->size].Surplus = RL->Route[RL->size].Pasger_Max - sold;
RL->Route[RL->size].WantBuy = (WantBuy_Type*)malloc(sizeof(WantBuy_Type));
RL->Route[RL->size].WantBuy->data = (Pasger_Type*)malloc(sizeof(Pasger_Type) * 100);
RL->Route[RL->size].WantBuy->rear = 0;
RL->Route[RL->size].WantBuy->front = 0;
if (RL->Route[RL->size].Surplus < 0)
{
printf("售票过多 系统崩溃");
exit(-1);
}
else if (RL->Route[RL->size].Surplus == 0)
{
printf("请输入有多少替补人员:\n");
int WB = 0;
scanf("%d", &WB);
for (int i = 0; i < WB; i++)
{
printf("请输入第%d名替补人员的购票数量 共有%d名替补人员\n", i + 1, WB);
scanf("%d", &RL->Route[RL->size].WantBuy->data[RL->Route[RL->size].WantBuy->rear].Amount);
printf("请输入第%d名替补人员的名字 \n", i + 1);
scanf("%s", RL->Route[RL->size].WantBuy->data[RL->Route[RL->size].WantBuy->rear].Name);
RL->Route[RL->size].WantBuy->data[RL->Route[RL->size].WantBuy->rear].Class = No;
RL->Route[RL->size].WantBuy->rear++;
}
}
RL->size++;
PS_Save(RL);
system("pause");
}
(4)查找航班信息
//查找航班信息
void PS_Search(Routes_List_Type* RL)
{
system("cls");
char TmpName[20];
printf("请输入终点站:");
scanf("%s", TmpName);
int i = 0;
for (i = 0; i < RL->size; i++)
{
if (strcmp(RL->Route[i].Terminal, TmpName) == 0)
{
printf("\n");
printf("航班号为 %s\n", RL->Route[i].Route_Name);
printf("飞机号为 %s\n", RL->Route[i].Plane_Name);
printf("飞行日为 %s\n", RL->Route[i].Fly_Week);
printf("余票量为 %d\n", RL->Route[i].Surplus);
break;
}
}
if (i == RL->size)
printf("没找到该航班\n");
printf("\n");
system("pause");
}
(5)订票系统
购票成功的直接进乘客席
不成功的询问是否进候补席
Y:进队列
N:返回菜单无事发生
//订票功能
void PS_BuyTicket(Routes_List_Type* RL)
{
system("cls");
printf("请输入 航班号 和 订票量:\n");
char Route_Name[20];
int Amount = 0;
scanf("%s", Route_Name);
scanf("%d", &Amount);
int i = 0;
for (i = 0; i < RL->size; i++)
{
if (strcmp(RL->Route[i].Route_Name, Route_Name) == 0)
{
if (RL->Route[i].Surplus >= Amount)
{
if (RL->Route->Bought == NULL)
{
RL->Route[i].Bought = (Bought_Type*)malloc(sizeof(Bought_Type));
RL->Route[i].Bought->data.Amount = Amount;
printf("请输入乘客舱位级别(1,2,3)\n");
scanf("%d", &RL->Route[i].Bought->data.Class);
printf("请输入乘客叫什么\n");
scanf("%s", RL->Route[i].Bought->data.Name);
RL->Route[i].Surplus -= Amount;
RL->Route[i].bought_number++;
RL->Route[i].Bought->next = NULL;
PS_Save(RL);
printf("购票成功!\n");
break;
}
Bought_Type* tmp = RL->Route[i].Bought;
while (tmp->next)
{
tmp = tmp->next;
}
tmp->next = (Bought_Type*)malloc(sizeof(Bought_Type));
tmp = tmp->next;
tmp->data.Amount = Amount;
printf("请输入乘客舱位级别(1,2,3)\n");
scanf("%d", &tmp->data.Class);
printf("请输入乘客叫什么\n");
scanf("%s", tmp->data.Name);
RL->Route[i].Surplus -= Amount;
RL->Route[i].bought_number++;
tmp->next = NULL;
PS_Save(RL);
printf("购票成功!\n");
break;
}
else
{
printf("您要搭乘的航班没有足够的票 您是否需要登记候补?(Y or N)\n");
char YorN = 0;
while (getchar() != '\n');
scanf("%c", &YorN);
if (YorN == 'Y')
{
RL->Route[i].WantBuy->data[RL->Route[i].WantBuy->rear].Amount = Amount;
RL->Route[i].WantBuy->data[RL->Route[i].WantBuy->rear].Class = No;
printf("请输入乘客叫什么\n");
scanf("%s", &RL->Route[i].WantBuy->data[RL->Route[i].WantBuy->rear].Name);
RL->Route[i].WantBuy->rear++;
PS_Save(RL);
printf("登记候补成功\n");
break;
}
else if (YorN == 'N')
{
printf("感谢您的支持 祝您生活愉快\n");
break;
}
else
{
printf("您并没有回答‘Y’or'N' 默认您不需要登记候补\n");
break;
}
}
}
}
if (i == RL->size)
printf("没找到该航班\n");
system("pause");
}
(6)退票信息
退票分为两种情况
1.候补席没有人或者没有合适的人
退票后直接从乘客席中将人拿下
2.候补席有人
退票后先从乘客席中将人拿下
再把候补席中的第一个合适人选 放入乘客席中
ps:
由于每个乘客都不一定买了几张机票
所以如果只买了一张机票的乘客退票了 而候补席的第一个人需要买两张票
所以候补席的第一个人虽然是先进的候补席 但不一定就能第一个出候补席
因此先进队列的人并不一定是先出来的人
所以! 这道题不用队列也挺好的 但我懒得改了
我把所有离开了候补席的乘客 信息都改成了”我需要9999张机票“
并且每次候补席出去人了 我就把front改成0
它也许不再是队列了 但挺好玩的
//退票功能
void PS_ReturnTicket(Routes_List_Type* RL)
{
system("cls");
printf("输入航班号 和 自己的姓名:\n");
char RouteName[20];
char PasgerName[20];
scanf("%s",RouteName);
scanf("%s",PasgerName);
int i = 0;
for (i = 0; i < RL->size; i++)
{
if (strcmp(RL->Route[i].Route_Name, RouteName) == 0)
{
if (strcmp(RL->Route[i].Bought->data.Name, PasgerName) == 0)
{
RL->Route[i].bought_number--;
RL->Route[i].Surplus += RL->Route[i].Bought->data.Amount;
RL->Route[i].Bought = RL->Route[i].Bought->next;
WantBuytoBuy(RL,i);
PS_Save(RL);
printf("%s 退票成功\n", PasgerName);
break;
}
Bought_Type* cur = RL->Route[i].Bought;
Bought_Type* tmp = cur;
while (strcmp(cur->data.Name,PasgerName) != 0 && cur->next != NULL)
{
tmp = cur;
cur = cur->next;
}
if (strcmp(cur->data.Name, PasgerName) == 0)
{
tmp->next = cur->next;
RL->Route[i].bought_number--;
RL->Route[i].Surplus += cur->data.Amount;
WantBuytoBuy(RL,i);
PS_Save(RL);
printf("%s 退票成功\n", PasgerName);
break;
}
else if (cur->next == NULL)
{
printf("没有这个人\n");
}
}
}
if (i == RL->size)
printf("没有这个航班\n");
system("pause");
}
//候补人员买票
void WantBuytoBuy(Routes_List_Type* RL,int n)
{
while (RL->Route[n].WantBuy->front != RL->Route[n].WantBuy->rear)
{
if (RL->Route[n].WantBuy->data[RL->Route[n].WantBuy->front].Amount <= RL->Route[n].Surplus)
{
Bought_Type* cur = RL->Route[n].Bought;
while (cur->next)
{
cur = cur->next;
}
cur->next = (Bought_Type*)malloc(sizeof(Bought_Type));
cur = cur->next;
printf("请候补人员%s 输入需要的乘客舱位级别(1,2,3)\n", RL->Route[n].WantBuy->data[RL->Route[n].WantBuy->front].Name);
scanf("%d", &RL->Route[n].WantBuy->data[RL->Route[n].WantBuy->front].Class);
cur->data = RL->Route[n].WantBuy->data[RL->Route[n].WantBuy->front];
cur->next = NULL;
RL->Route[n].bought_number++;
RL->Route[n].Surplus -= RL->Route[n].WantBuy->data[RL->Route[n].WantBuy->front].Amount;
RL->Route[n].WantBuy->data[RL->Route[n].WantBuy->front].Amount = 9999;
RL->Route[n].WantBuy->front = 0;
printf("候补人员%s 成功购票%d 张\n\n", cur->data.Name, cur->data.Amount);
}
RL->Route[n].WantBuy->front++;
}
}
(7)保存本地文件
这里的顺序和上面的读取顺序呼应了 都是wr,wb的二进制读写
//保存航班表
void PS_Save(Routes_List_Type* RL)
{
FILE* pf = fopen("Plane_System.dat", "wb");
if (pf == NULL)
return;
for (int i = 0; i < RL->size; i++)
{
fwrite(RL->Route + i, sizeof(Route_Info_Type), 1, pf);
Bought_Type* tmp0 = RL->Route[i].Bought;
while (tmp0)
{
fwrite(tmp0, sizeof(Bought_Type), 1, pf);
tmp0 = tmp0->next;
}
fwrite(&RL->Route[i].WantBuy->front, sizeof(int), 1, pf);
fwrite(&RL->Route[i].WantBuy->rear, sizeof(int), 1, pf);
fwrite(RL->Route[i].WantBuy->data, sizeof(Pasger_Type), RL->Route[i].WantBuy->rear, pf);
}
fclose(pf);
pf = NULL;
}
(8)七七八八的菜单
没
啥营养 就很菜单的菜单
void menu_Son()
{
printf("\t\t\t*************************************************\n");
printf("\t\t\t********** 航空客运订票系统 ***********\n");
printf("\t\t\t*************************************************\n");
printf("\t\t\t*************************************************\n");
printf("\t\t\t********** 1.显示所有航班信息 ***********\n");
printf("\t\t\t********** 2.增加航班信息 ***********\n");
printf("\t\t\t********** 3.查找航班信息 ***********\n");
printf("\t\t\t********** 4.订票 ***********\n");
printf("\t\t\t********** 5.退票 ***********\n");
printf("\t\t\t********** 0.退出系统 ***********\n");
printf("\t\t\t*************************************************\n");
printf("\t\t\t*************************************************\n");
printf("\t\t\t*************************************************\n");
printf("\t\t\t*************************************************\n");
printf("\t\t\t\t请输入:");
}
void menu()
{
int a = 0;
Routes_List_Type* Routes_List = (Routes_List_Type*)malloc(sizeof(Routes_List_Type));//航班表
PS_Init(Routes_List);
do {
system("cls");
menu_Son();
scanf("%d", &a);
switch (a)
{
case 1:
PS_Print(Routes_List);
break;
case 2:
PS_Push(Routes_List);
break;
case 3:
PS_Search(Routes_List);
break;
case 4:
PS_BuyTicket(Routes_List);
break;
case 5:
PS_ReturnTicket(Routes_List);
break;
case 0:
break;
default:
printf("没有该选项 请重新选择\n");
break;
}
} while (a);
}
三.程序的运行
总结
到了这里,关于【数据结构应用】航空客运订票系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!