目录
前言
一、作业要求介绍
二、各个函数的实现
1.头文件总结需要的功能
(1)结构体的定义
(2)各个功能的函数
2.各个函数的具体实现
(1)初始化
(2)打印航班信息表
(4)查找航班信息
(5)订票系统
(6)退票信息
(7)保存本地文件
(8)七七八八的菜单
三.程序的运行
总结
前言
本题的来源是数据结构期末作业。把作业写成博客是为了重新梳理一遍思路,也是向组员解释一下各个函数的功能。
一、作业要求介绍
总结一下 基本上就是以下几点
(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;elsetmp1->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;}elseprintf("无人购票\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);
}
三.程序的运行
gitee地址 : 0 · 621656a · 朱轶豪/铁豪进厂 - Gitee.com