前言:
广工数据结构课设,基本需求和选做内容以及一些小扩展均已实现,此博客仅展示一部分,实验报告文档、源代码和可运行程序(.exe文件)等可以去我的github或者码云上下载,如果对您有帮助,希望同时在github和码云给个star,谢谢!
github链接
码云链接
仓库内容:
一、问题描述
航空客运订票的业务活动包括: 查询航线、 客票预订和办理退票等。 试设计一个航空客运订
票系统, 以使上述业务可以借助计算机来完成。
二、 基本要求(已实现)
2.1 每条航线所涉及的信息有: 终点站名、 航班号、 飞机号、 飞行周日(星期几)、 乘员定额、余票量、 已订票的客户名单(包括姓名、 订票量、 舱位等级 1, 2 或 3)以及等候替补的客户名单(包括姓名、 所需票量);
2.2 作为示意系统, 全部数据可以只放在内存中;
2.3 系统能实现的操作和功能如下:
- 查询航线: 根据旅客提出的终点站名输出下列信息: 航班号、 飞机号、 星期几飞行, 最近一天航班的日期和余票额;
- 承办订票业务: 根据客户提出的要求(航班号、 订票数额)查询该航班票额情况, 若尚有余票, 则为客户办理订票手续, 输出座位号; 若已满员或余票额少于订票额, 则需重新询问客户要求。 若需要, 可登记排队候补;
- 承办退票业务: 根据客户提供的情况(日期、 航班), 为客户办理退票手续, 然后查询该航班是否有人排队候补, 首先询问排在第一的客户, 若所退票额能满足他的要求, 则为他办理订票手续, 否则依次询问其它排队候补的客户。
三、实现提示
两个客户名单可分别由线性表和队列实现。 为查找方便, 已订票客户的线性表应按客户姓名
有序, 并且, 为插入和删除方便, 应以链表作存储结构。 由于预约人数无法预计, 队列也应以链
表作存储结构。 整个系统需汇总各条航线的情况登录在一张线性表上, 由于航线基本不变, 可采
用顺序存储结构, 并按航班有序或按终点站名有序。 每条航线是这张表上的一个记录, 包含上述
八个域、 其中乘员名单域为指向乘员名单链表的头指针, 等候替补的客户名单域为分别指向队头
和队尾的指针。
四、选做内容(已实现)
当客户订票要求不能满足时, 系统可向客户提供到达同一目的地的其它航线情况。
读者还可充分发挥自己的想象力, 增加你的系统的功能和其它服务项目。
五、源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define FALSE -1
#define TRUE 1
typedef int Status;
//航班日期枚举类,星期一到星期天
enum Week {
Mon = 1, Tues = 2, Wed = 3, Thurs = 4, Fri = 5, Sat = 6, Sun = 7
};
//乘客节点
typedef struct CustomerNode {
char name[10];//客户姓名
int clientTickets;//客户订票量
char identification[20];//客户身份证号码
int rank;//舱位等级
CustomerNode *next;
} CustomerNode, *CusLinkList;
//候补队列中的节点
typedef struct WaitPassenger {
char name[10];//姓名
char identification[20]; //身份证
int preTickets;//预定的票量
struct WaitPassenger *next;
} WaitQNode, *PWait;
//候补队列
typedef struct Queue {
PWait front;//等候替补客户名单域的头指针
PWait rear;//等候替补客户名单域的尾指针
} LinkQueue;
//封装乘客的姓名和订票量和身份证
//用于候补客户出队时把关键字返回
typedef struct NameAndNumAndID {
char name[10];//姓名
char identification[20]; //身份证号码
int num;//订票量
} NameAndNumAndID;
//航班节点
typedef struct Flight {
char startPoint[20];//起点站名
char destination[20];//终点站名
char flightCodeID[20];//航班ID(相当于主键)
char planeNum[20];//飞机号
char day[20];//飞行日期(星期几)
int totalTickets;//乘员定额(总票数)
int left;//总余票量
int leftEconomicTicket; //经济票剩余量
int leftBusinessTicket; //商务票剩余量
Flight *next;
CusLinkList cusLinkList;//乘员名单域,指向乘员名单链表的头指针
LinkQueue waitQueue1;//经济舱候补,等候替补的客户名单域,指向一个队列
LinkQueue waitQueue2;//商务舱候补,等候替补的客户名单域,指向一个队列
} Flight, FlightNode, *PFlight;
//以下是接口声明
/**
*根据自己输入的航班ID查询并以指针形式返回
* @return 航班指针
*/
Flight *find();
/**
* 初始化带头结点的链队列
* @param q
*/
Status InitQueue(LinkQueue &q);
/**
* 初始化已订票乘客指针链表
* @param cusLinkList 航班中乘员链表的头指针
* @return
*/
Status InitCusLinkList(CusLinkList &cusLinkList);
/**
* 打印info航班的基本信息
* @param info
*/
void Display(struct Flight *info);
/**
* 增加航班时输入日期的辅助函数(1代表星期一,7代表星期日)
* @param day1 传进来的1-7中的一个
* @param day 数组类变量,可以返回回去给航班的日期变量
* @return 返回操作状态,输入是否合法
*/
Status IputDay(int day1, char day[]);
/**
*根据客户提出的终点站名输出航线信息
*/
void SearchFlight();
/**
* 打印订票乘员名单域的客户名单信息(不包括身份证)
*/
void PriCusInfo();
/**
* 订票功能模块
*/
void BookTickets();
/**
* 退票功能模块
*/
void ReturnTicket();
/**
* 搜索界面
*/
void SearchFace();
/**
* 订票界面
* 属于订票模块
*/
void BookticketFace();
/**
* 退票模块界面
*/
void ReturnTicketsFace();
/**
* 退出程序模块
*/
void GoodbyeFace();
/**
* 查询模块
* 打印全部航班信息
* @param flight 传入的是航班链表的头指针
*/
void PrintFilghtlist(Flight *flight);
/**
*菜单界面函数
* @return 返回选择的操作
*/
int MenuSelect();
/**
* 管理员界面
*/
void AdministratorFace();
/**
*根据客户提出的起点,终点站名输出航线信息
*/
void SearchFlight();
/**
* 推荐订票
* @param startPoint 起点
* @param destination 终点
* @param flight 原航班,用来辅助选出同一路线但不同航班ID的航班
*/
void Suggest(char startPoint[], char destination[], Flight *flight);
/**
* 将flight1的4个航班用头插入法插入到pFlight的链表中
* @param flight1 里面存有六个基本航班
* @return 返回操作是否成功
*/
Status Create(PFlight flight1);
/**
* 推荐同一路线的其他航班
* @param destination
* @param pflight 原航班,用来判断和新搜到的航班是否一样
* @return 找不到就返回FALSE,否则返回TRUE
*/
Status RecommendFlight(char startPoint[], char destination[], Flight *pflight);
/**
* 管理员插入航班时遍历航班,防止航班ID重复(航班ID相当于主键)
* @param flight
* @param flightCodeID
* @return 返回是否重复
*/
Status TraverseFlight(Flight *flight, char flightCodeID[]);
//接口代码实现
//定义全局指针变量pFlight,航班链表的头指针
Flight *pFlight;
//六个基本航班
Flight flight1[6] = {
{
"广州", "北京", "1", "B3333", "星期一", 10, 10, 5},
{
"广州", "北京", "2", "D5555", "星期二", 8, 8, 4},
{
"广州", "北京", "3", "L6666", "星期天", 10, 10, 5},
{
"上海", "广州", "4", "K9999", "星期三", 8, 8, 4},
{
"广州", "成都", "5", "K7777", "星期三", 10, 10, 5},
{
"成都", "广州", "6", "K8888", "星期三", 8, 8, 4}
};
/**
* 初始化航班链表
* 目的是要初始化移pFlight为头结点的空航班链表,录入航班信息和增加航班后将航班结点插入该链表
*/
void InitFlight() {
pFlight = (Flight *) malloc(sizeof(Flight));//申请头结点的空间
if (pFlight == NULL) exit(0);
pFlight->next = NULL;//将头结点h的指针域置为空
}
/**
* 将flight1的4个航班用头插入法插入到pFlight的链表中
* @param flight1 里面存有六个基本航班
* @return 返回操作是否成功
*/
Status Create(PFlight flight1) {
Flight *p = pFlight, *q;
for (int i; i < 6; i++) {
q = (Flight *) malloc(sizeof(Flight));
if (q == NULL)
return ERROR;
strcpy(q->startPoint, flight1[i].startPoint);
strcpy(q->destination, flight1[i].destination);
strcpy(q->flightCodeID, flight1[i].flightCodeID);
strcpy(q->planeNum, flight1[i].planeNum);
strcpy(q->day, flight1[i].day);
q->totalTickets = flight1[i].totalTickets;
q->left = flight1[i].totalTickets;
q->leftEconomicTicket = flight1[i].leftEconomicTicket;
q->leftBusinessTicket = flight1[i].totalTickets - flight1[i].leftEconomicTicket;
//初始化乘客链表
InitCusLinkList(q->cusLinkList);
//q->cusLinkList = (CustomerNode *) malloc(sizeof(CustomerNode));
//q->cusLinkList->next = NULL;
InitQueue(q->waitQueue1);
InitQueue(q->waitQueue2);
q->next = p->next;
p->next = q;
}
return OK;
}
/**
* 管理员操作
* 将新的航班结点插入到航班链表中,
* 采用头插入法
* @return 返回操作是否成功
*/
Status InsertFlight() {
FlightNode *q;//定义q为新增加的航班结点的指针的形参
Flight *p = pFlight;
int mark = 1;
while (mark != 0) {
q = (FlightNode *) malloc(sizeof(FlightNode));
if (q == NULL)
return ERROR;
printf("\t\t请依次输入以下内容\n");
printf("\t\t请输入航班ID\n");
scanf("%s", q->flightCodeID);
Status status = TraverseFlight(pFlight, q->flightCodeID);
if (status == ERROR) {
printf("该航班ID已经存在,请重新输入航班ID\n");
continue;
}
printf("\t\t请输入起点站名\n");
scanf("%s", q->startPoint);
printf("\t\t请输入终点站名\n");
scanf("%s", q->destination);
printf("\t\t请输入飞机号\n");
scanf("%s", q->planeNum);
printf("\t\t请输入飞行日期(1代表星期,2代表星期二.....7代表星期日)\n");
int day1;
scanf("%d", &am