航班订票系统

1.简介

 随着全球化的发展和人们出行需求的日益增长,航空旅行已成为现代生活不可或缺的一部分。为了提高旅客体验,简化预订流程,降低运营成本,航空公司和旅行代理机构迫切需要一个高效、可靠、用户友好的航班订票系统。本项目旨在设计和实现这样一个系统,它能够处理航班信息的查询、票价计算、座位预订、支付处理以及后续的行程管理等功能。

设计目标简述:

  1. 用户界面友好:系统应提供直观易用的界面,无论是通过网页还是移动应用程序,用户都能轻松进行航班搜索、比较和预订操作。
  2. 实时数据更新:系统需与航空公司的数据库实时同步,确保显示的航班信息、票价和可用座位数是最新的。
  3. 多渠道接入:支持多种设备和操作系统,允许用户通过电脑、手机或平板等不同终端进行预订。
  4. 安全性保障:在处理用户个人信息和支付信息时,系统必须采用加密技术和其他安全措施,保护用户隐私和交易安全。
  5. 客户服务集成:系统内嵌或链接到客户服务中心,方便用户在遇到问题时快速获得帮助。
  6. 性能优化:保证在高并发情况下系统仍能稳定运行,减少响应时间,提升用户体验。
  7. 可扩展性和维护性:设计时应考虑未来可能的功能扩展和技术升级,使系统易于维护和更新。
  8. 数据分析和报告:系统应具备数据收集和分析功能,帮助航空公司了解市场趋势,优化航班安排和定价策略。

通过实现上述目标,航班订票系统将成为航空公司和旅行代理机构的得力助手,同时也极大地提升了旅客的预订体验,促进了航空业的数字化转型。

2 问题分析

2.1需求描述

在进一步分析航班订票系统的需求时,我们深入探讨了用户、航空公司以及旅行代理机构等各方的需求和期望。以下是对需求的详细描述:

首先,对于用户而言,他们期望系统能够提供方便快捷的航班查询功能,允许他们根据出发地、目的地、出发时间等条件筛选出合适的航班。同时,用户还希望系统能够实时显示各航班的票价、剩余座位数等信息,以便他们做出最优的预订决策。此外,系统还应支持多种支付方式,保障交易的安全和便捷性。最后,用户还期望系统能够提供行程管理的功能,方便他们随时查看和修改自己的订单信息。

对于航空公司而言,他们希望系统能够准确、高效地处理大量的航班信息和预订请求。系统应具备实时更新航班信息的能力,以便航空公司能够及时调整航班计划和票价策略。此外,系统还应提供数据分析和报告的功能,帮助航空公司了解市场趋势、客户需求以及运营状况,从而做出更明智的决策。

对于旅行代理机构而言,他们需要一个能够与航空公司系统对接的、功能强大的航班订票系统,以便为客户提供一站式的旅行预订服务。系统应支持代理机构与航空公司之间的数据同步和交互,确保代理机构能够为客户提供最新、最准确的航班信息,并可以随时调整航班信息。

2.2系统功能描述

在航班订票系统的设计和实现过程中,存储结构的选择至关重要。为了保障数据的高效存储和访问,我们采用了关系型数据库作为主要的存储结构。关系型数据库以其结构化、易于管理和维护的特点,非常适合处理航班信息、用户数据、订单记录等复杂且关联度高的数据。

具体来说,我们定义了以下几个主要的数据库表:

  1. 航班信息表:用于存储航班的详细信息,包括航班号、出发地、目的地、起飞时间、到达时间、机型、票价等。通过该表,我们可以快速查询和更新航班信息,满足用户对航班查询和预订的需求。
  2. 可以随时修改相对应的航班信息,包括单独修改单项信息,灵活方便。
  3. 可以随时删除航班信息,用来应对因环境或不可抗力而取消的航班。

3 数据结构定义

3.1逻辑结构定义

在程序中我使用了线性表的结构,因为在程序中定义的城市,时间,票价等都是有线性关系的数据

数据结构定义:

Passenger 结构体:用于存储航班信息,包括航班号、起飞时间、到达城市、票价、是否满仓和剩余位置。

node 结构体:用于构建链表,每个节点包含一个 Passenger 结构体和指向下一个节点的指针。

功能函数:

menu():显示主菜单,提供用户操作选择。

inputpassenger(node* head):输入新的航班信息并添加到链表尾部。

printpassenger(node* head):遍历链表并打印所有航班信息。

modifypassenger(node* head):根据航班号查找并修改指定航班信息。

findpassenger(node* head):根据航班号查找并显示指定航班信息。

writepassenger(node* head):将链表中的航班信息写入到文件中。

readinfofromfile(node* head):从文件中读取航班信息并构建链表。

delectpassenger(node* head):根据航班号查找并删除指定航班信息。

countpassenger(node* head):统计链表中航班信息的数量。

主函数:

main():程序入口,负责创建链表头节点,读取文件信息,显示菜单,并根据用户选择调用不同的功能

其他函数:

system("pause") 和 system("cls"):用于暂停程序和清空控制台。

3.2存储结构选择及定义

使用了链式存储

该航班管理系统采用了 单向链表 作为存储结构。

链表的定义:

typedef struct _node

{

    Passenger passenger;

    struct _node* next;

}node;

链表节点包含两部分

数据域 : 存储航班信息,包括航班号、起飞时间、到达城市、票价、是否满仓和剩余位置。

指针域 : 指向下一个节点,用于实现链表的链接。

链表的特点:

动态内存分配: 可以根据需要动态地增加或删除节点,灵活地管理航班信息。

插入和删除操作效率高: 只需要修改指针,不需要移动其他元素。

随机访问效率低: 需要从头节点开始遍历链表才能找到特定节点。

使用链表的优势:

代码中,航班信息是动态添加的,使用链表可以方便地管理这些动态数据。

链表可以实现各种操作,例如查找、修改、删除和统计航班信息。

代码中链表的使用:

头结点: 用于指向链表的第一个节点,方便进行操作。

动态内存分配: 使用 malloc 函数为每个节点分配内存。

遍历链表: 使用指针 move 遍历链表,访问每个节点的数据。

插入节点: 将新节点插入到链表的尾部。

删除节点: 删除链表中的特定节点。

释放内存: 使用 free 函数释放链表节点占用的内存。

4 算法设计

4.1算法描述

我负责对代码进行整合与对页面进行设计,我首先使用了main函数将三个新定义函数给整合起来,有打印出来了一个用户页面。

主函数: 创建一个链表头结点,读取航班信息文件,进入主循环,根据用户选择执行不同的功能。

菜单函数: 显示功能菜单,提示用户输入选择。

录入航班信息函数: 创建一个新节点,输入航班信息,并将其添加到链表尾部。

打印航班信息函数: 遍历链表,打印每个节点的航班信息

查找航班信息函数: 遍历链表,查找并打印指定航班号的航班信息。

修改航班信息函数: 遍历链表,找到指定航班号的航班,根据用户选择修改其信息。

删除航班信息函数: 遍历链表,找到指定航班号的航班,并将其从链表中删除。

统计航班函数: 遍历链表,统计航班总数。

写入航班信息文件函数: 遍历链表,将所有航班信息写入到文件中。

读取航班信息文件函数: 从文件中读取航班信息,并将其添加到链表中。

4.2主要模块及函数设计(伪码描述)

int main() {

node* head = (node*)malloc(sizeof(node));//创建头结点

head->next = NULL;

readinfofromfile(head);

while (1)

{

menu();

char c = getchar();

switch (c)

{

case '0':

printf("录入信息\n");

break;

case '1':

printf("查找信息\n");

break;

case '2':

printf("浏览信息\n");

break;

case '3':

printf("修改信息\n");

break;

case '4':

printf("删除信息\n");

break;

case '5':

printf("剩余位置统计\n");

break;

case '6':

system("cls");

printf("退出成功");

system("pause");

exit(0);

break;

default:

break;

}

system("pause");

system("cls");

}

return 0;

}

void menu()

{

printf("*********************************\n");

printf("*\t  航班管理系统\t\t*\n");

printf("*********************************\n");

printf("*\t  请选择功能\t\t*\n");

printf("*\t  0.录入航班信息\t*\n");

printf("*\t  1.查找航班信息\t*\n");

printf("*\t  2.浏览所有航班\t\t*\n");

printf("*\t  3.修改航班信息\t*\n");

printf("*\t  4.删除航班信息\t*\n");

printf("*\t  5.统计航班\t*\n");

printf("*\t  6.退出系统\t\t*\n ");

printf("*********************************\n");

printf("*    请输入0~6对系统进行操作    *\n");

4.3 主程序的流程以及各个模块之间的调用关系设计

主程序流程

初始化

创建头结点 head,指向 NULL。

从文件 stu.info 中读取航班信息,填充链表。

循环执行

显示菜单,提示用户选择功能。

根据用户输入,调用相应的功能函数:

录入航班信息

查找航班信息

浏览所有航班信息

修改航班信息

删除航班信息

统计航班数量

退出系统

每次执行完功能后,清空控制台,并提示用户继续操作或退出。

退出

当用户选择 6 时,退出程序。

模块调用关系设计

主函数 :

调用 menu() 显示菜单。

根据用户选择调用其他功能函数。

功能函数:

inputpassenger(): 录入航班信息,并调用 writepassenger() 保存到文件。

printpassenger(): 浏览所有航班信息。

findpassenger(): 查找航班信息。

modifypassenger(): 修改航班信息,并调用 writepassenger() 保存到文件。

writepassenger(): 将航班信息写入文件。

readinfofromfile(): 从文件读取航班信息到链表。

delectpassenger(): 删除航班信息,并调用 writepassenger() 保存到文件。

countpassenger(): 统计航班数量。

5 算法分析

每次查询都对数据进行遍历,可以减少时间和空间复杂度

由于代码中包含了多个函数,我将分别对每个函数进行算法分析:

1. menu() 函数

功能: 打印菜单选项。

时间复杂度: O(1) - 常数时间,因为只进行了一次打印操作。

空间复杂度: O(1) - 常数空间,因为没有使用额外的存储空间。

2. inputpassenger(node* head) 函数

功能: 录入航班信息。

时间复杂度:

    最好情况: O(1) - 如果链表为空,则直接插入新节点。

    最坏情况: O(n) - 如果链表很长,需要遍历整个链表才能找到最后一个节点。

    平均情况: O(n) - 平均需要遍历链表的一半才能找到插入位置。

空间复杂度: O(1) - 常数空间,因为只分配了一个新节点。

3. printpassenger(node* head) 函数

功能: 浏览所有航班信息。

时间复杂度:

    最好情况: O(n) - 需要遍历整个链表才能打印所有信息。

    最坏情况: O(n) - 与最好情况相同。

    平均情况: O(n) - 与最好情况相同。

空间复杂度: O(1) - 常数空间,因为没有使用额外的存储空间。

4. findpassenger(node* head) 函数

功能: 查找航班信息。

时间复杂度:

    最好情况: O(1) - 如果要查找的航班号是链表的第一个节点。

    最坏情况: O(n) - 如果要查找的航班号不在链表中,需要遍历整个链表。

    平均情况: O(n) - 平均需要遍历链表的一半才能找到目标航班号。

空间复杂度: O(1) - 常数空间,因为没有使用额外的存储空间。

5. modifypassenger(node* head) 函数

功能: 修改航班信息。

时间复杂度:

    最好情况: O(1) - 如果要修改的航班号是链表的第一个节点。

    最坏情况: O(n) - 如果要修改的航班号不在链表中,需要遍历整个链表。

    平均情况: O(n) - 平均需要遍历链表的一半才能找到目标航班号。

空间复杂度: O(1) - 常数空间,因为没有使用额外的存储空间。

6. writepassenger(node* head) 函数

功能: 将航班信息写入文件。

时间复杂度:

    最好情况: O(n) - 需要遍历整个链表才能将所有信息写入文件。

    最坏情况: O(n) - 与最好情况相同。

    平均情况: O(n) - 与最好情况相同。

空间复杂度: O(1) - 常数空间,因为没有使用额外的存储空间。

7. readinfofromfile(node* head) 函数

功能: 从文件读取航班信息。

时间复杂度:

    最好情况: O(n) - 需要读取文件中的所有信息才能创建链表。

    最坏情况: O(n) - 与最好情况相同。

    平均情况: O(n) - 与最好情况相同。

空间复杂度: O(n) - 线性空间,因为需要为每个航班信息分配一个节点。

8. delectpassenger(node* head) 函数

功能: 删除航班信息。

时间复杂度:

    最好情况: O(1) - 如果要删除的航班号是链表的第一个节点。

    最坏情况: O(n) - 如果要删除的航班号不在链表中,需要遍历整个链表。

    平均情况: O(n) - 平均需要遍历链表的一半才能找到目标航班号。

空间复杂度: O(1) - 常数空间,因为没有使用额外的存储空间。

9. countpassenger(node* head) 函数

功能: 统计航班数量。

时间复杂度:

    最好情况: O(n) - 需要遍历整个链表才能统计所有航班数量。

    最坏情况: O(n) - 与最好情况相同。

    平均情况: O(n) - 与最好情况相同。

空间复杂度: O(1) - 常数空间,因为没有使用额外的存储空间。

6 编码实现

使用C语言

#define _CRT_SECURE_NO_WARNINGS 
#pragma warning(disable:6031)//消除返回值对scanf的忽略警告
#include<stdio.h>
#include<stdlib.h>
typedef struct _passenger
{
	int num;//航班号
	char time[20];//起飞时间
	char city[20];//到达城市
	char price[20];//票价
	bool if_full[20];//是否满仓
	int  remainder;//剩余位置
}Passenger;
typedef struct _node
{
	Passenger passenger;
	struct _node* next;
}node;
void menu();
void inputpassenger(node* head);
void printpassenger(node* head);
void modifypassenger(node* head);
void findpassenger(node* head);
void writepassenger(node* head);
void readinfofromfile(node* head);
void delectpassenger(node* head);
void countpassenger(node* head);
int main() {
	node* head = (node*)malloc(sizeof(node));//创建头结点 
	head->next = NULL;
	readinfofromfile(head);
	while (1)
	{
		menu();
		char c = getchar();
		switch (c)
		{
		case '0':
			printf("录入信息\n");
			inputpassenger(head);
			break;
		case '1':
			printf("查找信息\n");
			findpassenger(head);
			break;
		case '2':
			printf("浏览信息\n");
			printpassenger(head);
			break;
		case '3':
			printf("修改信息\n");
			
			modifypassenger(head);
			break;
		case '4':
			printf("删除信息\n");
			delectpassenger(head);
			break;
		case '5':
			printf("剩余位置统计\n");
			countpassenger(head);
			break;
		case '6':
			system("cls");
			printf("退出成功");
			system("pause");
			exit(0);
			break;
		default:
			break;
		}
		system("pause");
		system("cls");
	}

	return 0;
}

void menu()
{
	printf("*********************************\n");
	printf("*\t  航班管理系统\t\t*\n");
	printf("*********************************\n");
	printf("*\t  请选择功能\t\t*\n");
	printf("*\t  0.录入航班信息\t*\n");
	printf("*\t  1.查找航班信息\t*\n");
	printf("*\t  2.浏览所有航班\t\t*\n");
	printf("*\t  3.修改航班信息\t*\n");
	printf("*\t  4.删除航班信息\t*\n");
	printf("*\t  5.统计航班\t*\n");
	printf("*\t  6.退出系统\t\t*\n ");
	printf("*********************************\n");
	printf("*    请输入0~6对系统进行操作    *\n");
}



void inputpassenger(node* head)
{

	node* fresh = (node*)malloc(sizeof(node));
	if (fresh == NULL) {
		printf("分配内存失败");
		exit(-1);
	}
	else
		fresh->next = NULL;
	printf("请输入航班相关信息\n");
	printf("航班号\n");
	scanf("%d", &fresh->passenger.num);
	printf("时间\n");
	scanf("%s", fresh->passenger.time);
	printf("城市\n");
	scanf("%s", fresh->passenger.city);
	printf("票价\n");
	scanf("%s", fresh->passenger.price);
	printf("是否满仓\n");
	scanf("%s", fresh->passenger.if_full);
	printf("剩余位置\n");
	scanf("%d", &fresh->passenger.remainder);
	node* move = head;
	while (move->next != NULL)
	{
		move = move->next;
	}
	move->next = fresh;
	writepassenger(head);
	system("pause");//暂停程序 
	system("cls"); //清空控制台 

}

void printpassenger(node* head)
{
	node* move = head->next;
	while (move != NULL)
	{
		printf("航班号\t时间\t城市\t票价\t是否满仓\t剩余位置\n");
		printf("%d\t%s\t%s\t%s\t%s\t%d\n", move->passenger.num, move->passenger.time, move->passenger.city,
			move->passenger.price, move->passenger.if_full, move->passenger.remainder);
		move = move->next;
	} 
	system("pause");//暂停程序 
	system("cls"); //清空控制台 
}

void findpassenger(node* head)
{
	printf("请输入要查找的航班号");
	int num;
	scanf("%d", &num);
	node* move = head->next;
	while (move != NULL)
	{
		if (num == move->passenger.num)
		{
			printf("航班号\t时间\t城市\t票价\t是否满仓\t剩余位置\n");
			printf("%d\t%s\t%s\t%s\t%s\t%d\n", move->passenger.num, move->passenger.time, move->passenger.city,
				move->passenger.price, move->passenger.if_full, move->passenger.remainder);
			system("pause");//暂停程序 
			system("cls"); //清空控制台
		}
		move = move->next;
	}
	printf("未找到航班信息");
	system("pause");//暂停程序 
	system("cls"); //清空控制台 
}

void modifypassenger(node* head)
{
	printf("请输入需要修改的航班号\n");
	int num;
	scanf("%d", &num);
	node* move = head->next;
	while (move != NULL)
	{
		if (move->passenger.num == num)
		{
			    int number;
			    printf("请输入0~5分别代表航班号、时间、城市、票价、是否满仓、剩余位置\n");
				scanf("%d",&number);
				switch (number)
				{
				case 0:
					printf("修改航班号\n");
					printf("请输入需要修改后的航班号\n");
					scanf("%d", &move->passenger.num);
					writepassenger(head);
					printf("修改成功\n");
					system("pause");//暂停程序 
					system("cls"); //清空控制台 
					break;
				case 1:
					printf("修改到达时间\n");
					printf("请输入需要修改后的时间\n");
					scanf("%s", &move->passenger.time);
					writepassenger(head);
					printf("修改成功\n");
					system("pause");//暂停程序 
					system("cls"); //清空控制台 
					break;
				case 2:
					printf("修改到达城市\n");
					printf("请输入需要修改后的城市\n");
					scanf("%s", &move->passenger.city);
					writepassenger(head);
					printf("修改成功\n");
					system("pause");//暂停程序 
					system("cls"); //清空控制台 
					break;
				case 3:
					printf("修改票价\n");
					printf("请输入需要修改后的票价\n");
					scanf("%s", &move->passenger.price);
					writepassenger(head);
					printf("修改成功\n");
					system("pause");//暂停程序 
					system("cls"); //清空控制台 
					break;
				case 4:
					printf("修改是否满仓\n");
					printf("请输入需要修改后的是否满仓\n");
					scanf("%s", &move->passenger.if_full);
					writepassenger(head);
					printf("修改成功\n");
					system("pause");//暂停程序 
					system("cls"); //清空控制台 
					break;
				case 5:
					printf("修改剩余位置\n");
					printf("请输入需要修改后的剩余位置\n");
					scanf("%d", &move->passenger.remainder);
					writepassenger(head);
					printf("修改成功\n");
					system("pause");//暂停程序 
					system("cls"); //清空控制台 
					break;
				default:
					break;
				}
			return;
		}
		move = move->next;
	}
	printf("未找到航班信息\n");
	system("pause");//暂停程序 
	system("cls"); //清空控制台 
}

void writepassenger(node* head)
{
	FILE* file = fopen("./stu.info", "w");
	if (file == NULL) {
		printf("打开文件失败\n");
		return;
	}
	node* move = head->next;
	while (move != NULL)
	{
		if (fwrite(&move->passenger, sizeof(Passenger), 1, file) != 1) {
			printf("写入失败\n");
			return;
		}
		move = move->next;
	}
	fclose(file);
	printf("数据保存成功\n");
}

void readinfofromfile(node* head)
{
	FILE* file = fopen("./stu.info", "r");
	if (!file) {
		printf("没有航班文件,跳过读取\n");
		return;
	}
	node* fresh = (node*)malloc(sizeof(node));
	if (fresh == NULL) {       //取消对NULL指针fresh的引用警告
		exit(-1);
	}
	else
		fresh->next = NULL;
	node* move = head;
	while (fread(&fresh->passenger, sizeof(Passenger), 1, file) == 1)
	{
		if (move->next != NULL) {
			move->next = fresh;
		}
		move = fresh;
		node* fresh = (node*)malloc(sizeof(node));
		if (fresh == NULL) {
			printf("分配内存失败");
			exit(-1);
		}
		else
			fresh->next = NULL;
	}
	free(fresh);
	fclose(file);
	printf("读取成功\n");
}

void delectpassenger(node* head)
{
	printf("请输入需要删除航班的航班号");
	int num;
	scanf("%d", &num);
	node* move = head;
	while (move->next != NULL)
	{
		if (move->next->passenger.num == num)
		{
			node* temp = move->next;
			move->next = move->next->next;
			free(temp);
			temp = NULL;
			writepassenger(head);
			printf("删除成功");
			system("pause");//暂停程序 
			system("cls"); //清空控制台 
		}
		else {
			printf("未找到航班信息");
			system("pause");//暂停程序 
			system("cls"); //清空控制台
		}
		move = move->next;
	}
}

void countpassenger(node* head)
{
	int count = 0;
	node* move = head->next;
	while (move != NULL)
	{
		count++;
		move = move->next;
	}
	printf("总的航班数%d\n", count);
	system("pause");
	system("cls");
}

7 调试、测试与运行记录

在航班管理系统的开发过程中,调试、测试与运行记录是确保系统稳定、可靠的关键环节。本部分将详细记录调试过程中遇到的问题、测试的方法和结果,以及运行记录的要点。

调试过程:

在调试阶段,我们主要关注以下几个方面:

-内存管理:检查是否存在内存泄漏、野指针等问题。通过编译器和内存检测工具,确保每个分配的内存块都有正确的释放操作。

-函数接口:验证各个函数之间的参数传递是否正确,返回值是否符合预期。特别关注文件读写函数,确保数据能够正确加载和保存。

-逻辑错误:通过逐步跟踪程序执行流程,检查逻辑判断是否出错

8 总结

通过本次航班管理系统的设计与实现,我们深入了解了如何使用C语言进行数据处理和文件操作。系统实现了航班信息的录入、查找、浏览、修改、删除以及统计功能,满足了用户的基本需求。在开发过程中,我们注重代码的可读性和可维护性,采用了模块化的设计思想,使得每个功能都能独立运行和测试。同时,我们也对系统进行了充分的调试和测试,确保其在各种情况下都能稳定运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值