航班信息查询和检索系统

课程设计

哈夫曼编码/译码器
教室数据管理
电网建设造价计算
计算机竞赛管理系统


一、设计任务及要求

实现对飞机航班信息进行排序和查找,可按照航班号、起点站、到达站、起飞时间和到达时间等信息进行查询。

对飞机航班信息进行排序采用折半查找思想完成查找。可按照航班号、起点站、到达站、起飞时间和到达时间等信息进行查询。测试的数据不得少于10个,不得有重复的航班。

二、设计导向

1. 设计目的

  1. 巩固和加深对数据结构课程所学知识的理解,了解并掌握数据结构与算法的设计方法;
  2. 初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;
  3. 提高综合运用所学的理论知识和方法,独立分析和解决问题的能力;
  4. 训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风;
  5. 培养查阅资料,独立思考问题的能力。

2. 总体设计方案

设计航班信息查询和检索系统的总体思路:
(1)先定义一个储存航班信息查询的数据类型。
(2)由用户录入航班数据,对数据进行排序。
(3)执行数据查询和检索。
(4)搜索错误时能够进行报错。

总体设计框架图:在这里插入图片描述

3. 详细设计

(1)根据设计要求定义相关数据类型
用结构体存入航班相关信息。如起点站、终点站、航班期、起飞时间、到达时间、机型、票价、航班号等。

(2)冒泡排序算法对航班号排序
冒泡排序是所有排序算法中最简单、最易实现的算法,有时也称为起泡排序算法。使用冒泡排序算法对 n 个数据进行排序,实现思路是:从待排序序列中找出一个最大值或最小值,这样的操作执行 n-1 次,最终就可以得到一个有序序列。首先我们已经定义有一个存储航班信息的数组,里面存放着待排序的航班号,我们如果需要把比较大的元素排在前面,把小的元素排在后面,那么需要从尾到头开始下面的比较操作:从尾部开始比较相邻的两个元素,如果尾部的元素比前面的大,就交换两个元素的位置。往前对每个相邻的元素都做这样的比较、交换操作,这样到数组头部时,第 1 个元素会成为最大的元素。重新从尾部开始第 1、2 步的操作,除了在这之前头部已经排好的元素。继续对越来越少的数据进行比较、交换操作,直到没有可比较的数据为止,排序完成。

(3)二分查找算法
在有序序列中,使用二分查找算法搜索目标元素的核心思想是:不断地缩小搜索区域,降低查找目标元素的难度。以在升序序列中查找目标元素为例,二分查找算法的实现思路是:初始状态下,将整个序列作为搜索区域(假设为 [B, E]);找到搜索区域内的中间元素(假设所在位置为 M),和目标元素进行比对。如果相等,则搜索成功;如果中间元素大于目标元素,表明目标元素位于中间元素的左侧,将 [B, M-1] 作为新的搜素区域;反之,若中间元素小于目标元素,表明目标元素位于中间元素的右侧,将 [M+1, E] 作为新的搜素区域;重复执行第二步,直至找到目标元素。如果搜索区域无法再缩小,且区域内不包含任何元素,表明整个序列中没有目标元素,查找失败。
二分查找有个很重要的特点,就是不会查找数列的全部元素,而查找的数据量其实正好符合元素的对数,正常情况下每次查找的元素都在一半一半地减少。当然,最好的情况是只查找一次就能找到,但是在最坏和一般情况下的确要比顺序查找好了很多。

(4)调用函数
除了主函数main()外,其他各个函数相对于其他函数来说是独立的,函数的使用都由主函数main()调用和使用。

(5)主程序流程图
程序开始后,先录入航班信息。当完成航班信息录入后,系统通过航班号对航班信息排序。用户选择搜索系统后,若输入航班信息关键词没有错误,则可通过航班号、起点站、终点站、起飞时间、到达时间进行搜索,当搜索完毕可退出程序。
在这里插入图片描述

4. 系统测试与结果分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、课程设计总结

最开始拿到这个课题的时候,脑子里没有很清晰的思路,所以走了很多弯路。例如是先调用查找函数还是排序函数没有弄清楚,导致代码的结果不是很理想。但还好最后又回到原点,通过程序框图一步一步的试错,不断调试、改进代码,最后成功完成了本次的课程设计。

在本次实验过程中,输入错误还是存在的问题,但能很快的通过编译解决,一些编译不能发现的问题,在组建过程中也能发现并解决。这次实验的过程中遇到了很多问题,定义的过程中存在定义不清楚的问题,还有一些模糊定义和重定义的问题出现。在程序的定义过程中,存在着函数的调用失败的问题,在调用过程中不能正常调用,通过把调用的函数直接用在程序中,不通过调用的方法,使得程序正常运行。本次实验的问题只要通过调试和对整个程序的理解,便可以解决所有的发现的问题。

本次实验利用二分查找法很快的完成了对航班信息的查找,使我对二分查找有了一个很好的掌握。其查找过程是先确定待查记录所在的范围(区间),然后逐步缩小范围直到找到或找不到该记录为止

在实验过程中,程序中许多定义需要我们有一个很仔细的了解,比如上述的对字符长度的定义,这需要对所定义的对象给一个合理的字符长度,在输入的过程中才不会出现因输入的字符长度过长而不能识别。通过这次实验,使得对于查找以及检索有了一个很好的掌握,让我们在以后的程序设计过程中对于类似的函数定义有一个很清晰的过程以及了解。

这次课程设计使我的对数据结构的理解加深,提高综合运用本课程所学知识的能力。同时培养了我查阅参考书,查阅手册及文献资料的能力。以及培养独立思考,深入研究,分析问题、解决问题的能力。通过实际编译系统的分析设计、编程调试,掌握应用软件的分析方法和工程设计方法。通过课程设计,培养了我严肃认真的工作作风,逐步建立正确的生产观念、经济观念和全局观念。在这次设计过程中,体现出自己单独设计模具的能力以及综合运用知识的能力,体会了学以致用、突出自己劳动成果的喜悦心情,也从中发现自己平时学习的不足和薄弱环节,从而加以弥补。

这次课程设计,我在编辑中犯了不应有的错误,设计统计字符和合并时忘记应该怎样保存数据,对文件的操作也很生疏。在不断分析后明确并改正了错误和疏漏,我的程序有了更高的质量。

四、附录:源程序清单

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Max 100
#define keylength 7
typedef char KeyType;

typedef struct 
{
	char start[7];		//起点站
	char end[7];		//终点站
	char sche[30];		//航班期
	char time1[5];		//起飞时间
	char time2[5];		//到达时间
	char mode1[3];		//机型
	int price;			//票价
} InfoType;				//航班记录类型

typedef struct
{
	KeyType keys[keylength];//关键字
	InfoType others;
	int next;
} SLNode;				//静态链表结点类型

typedef struct 
{
	SLNode sl[Max];     //静态链表的可利用空间,s1[0]为头结点
	int keynum;			//记录当前关键字字符个数
	int length;			//当前表长
} SLList;				//静态链表类型

//冒泡排序
SLList BubbleSort(SLList L) 
{
	int m, flag, j;
	SLNode temp; 
	m = L.length - 1;
	flag = 1; 
	while ((m > 1) && (flag == 1)) 
	{
		flag = 0;  
		for (j = 1; j < L.length; ++j)
			if (strcmp(L.sl[j].keys, L.sl[j + 1].keys) > 0) 
			{
				flag = 1;
				temp = L.sl[j];
				L.sl[j] = L.sl[j + 1];
				L.sl[j + 1] = temp;
			}
		--m;
	}
	return L;
}

//查找算法的实现
int BinSearch(SLList L, KeyType key[]) 	//二分查找函数
{	
    int low, high, mid;
	low = 1;
	high = L.length;
	while (low <= high) 
	{
		mid = (high + low) / 2 ;
		if (strcmp(key, L.sl[mid].keys) > 0)
			low = mid + 1;
		else if (strcmp(key, L.sl[mid].keys) < 0)

			high = mid - 1;
		else
			return mid;
	}
	return -1;
}//BinSearch

void Display(SLList, int i);				//声明输出函数

//顺序查找函数
void SeqSearch(SLList L, KeyType key[], int i) 
{
	int j, k, m = 0;
	for (j = 1; j <= L.length; j++) 
	{
		switch (i) {
			case 1:
				k = strcmp(key, L.sl[j].keys);
				break;
			case 2:
				k = strcmp(key, L.sl[j].others.start);
				break;
			case 3:
				k = strcmp(key, L.sl[j].others.end);
				break;
			case 4:
				k = strcmp(key, L.sl[j].others.time1);
				break;
			case 5:
				k = strcmp(key, L.sl[j].others.time2);
				break;
		}
		if (k == 0) 
		{
			m = 1;
			Display(L, j);
		}
	}
	if (m == 0)
		printf("无此航班信息,可能是输入错误:\n");
}

//输入输出函数
void Display(SLList L, int i) 
{
	if (i == -1)
		printf("无此航班信息,可能是输入错误:\n");
	else {
		printf("航班号 起点站 终点站 航班期	起飞时间 到达时间 机型 票价\n");
		printf("%s,%s,%s,%s,%s,%s,%s,%d\n", L.sl[i].keys,
		       L.sl[i].others.start, L.sl[i].others.end, L.sl[i].others.sche,
		       L.sl[i].others.time1, L.sl[i].others.time2, L.sl[i].others.mode1,
		       L.sl[i].others.price);
	}
}

//查询检索菜单控制程序
void serachcon(SLList L) 
{
	int i = 1, k;
	KeyType key[keylength], k1[4];
	while (i >= 1 && i <= 5) {
		printf("*********************************************************\n");
		printf("");
		printf("*		      航班信息查询系统		        *\n");
		printf("*********************************************************\n");
		printf("*			1.航 班 号			*\n");
		printf("*			2.起 点 站			*\n");
		printf("*			3.终 点 站			*\n");
		printf("*			4.起飞时间			*\n");
		printf("*			5.到达时间			*\n");
		printf("*			0.退出系统			*\n");
		printf("*********************************************************\n");
		printf("			请选择(1-5)			 \n");
		scanf("%d", &i);
		switch (i) {
			case 1:
				printf("输入要查询的航班号(字母要大写):");
scanf("%s", key);
				k = BinSearch(L, key);
				Display(L, k);
				break;

			case 2:
				printf("输入要查询的航班起点站名:");
				scanf("%s", key);
				SeqSearch(L, key, i);
				break;

			case 3:
				printf("输入要查询的航班终点站名:");
				scanf("%s", key);
				SeqSearch(L, key, i);
				break;

			case 4:
				printf("请输入要查询的航班起飞时间:");
				scanf("%s", k1);
				SeqSearch(L, k1, i);
				break;

			case 5:
				printf("输入要查询的航班到达时间:");
				scanf("%s", k1);
				SeqSearch(L, k1, i);
				break;

			case 0:
				printf("祝您飞行愉快,再见!\n");
				return ;
		}
	}
}

//输入航班记录函数
SLList InputData(SLList L) 
{
	L.length = 0;
	int i = ++L.length;
	char yn = 'y';
	while (yn == 'y' || yn == 'Y') 
	{
	//	printf("\n");
		printf("请录入航班信息:\n");
		printf("航班号 起点站 终点站 航班期 起飞时间 到达时间 机型 票价\n");
		scanf("%s %s %s %s %s %s %s %d", L.sl[i].keys,
		      L.sl[i].others.start, L.sl[i].others.end, L.sl[i].others.sche,
		      L.sl[i].others.time1, L.sl[i].others.time2, L.sl[i].others.mode1,
		      &L.sl[i].others.price);
		++i;
		printf("继续输入吗?y/n:");
		getchar();
		scanf("%c", &yn);
		printf("\n");

	}
	L.length = i - 1  ;
	return L;
}

//主函数
int main(void) 
{
	int i, m, flag;
	SLList L;
	L.keynum = 7;
	L = InputData(L);
	printf("\n");
	printf("已为您查询到的航班数:");		//输入航班记录
	printf("%d\n",L.length);
	//printf("航班号 起点站 终点站 航班期 起飞时间 到达时间 机型 票价\n");
	for (int i = 1; i <= L.length; i++)
	L = BubbleSort(L); 			//冒泡排序
	printf("航班号 起点站 终点站 航班期 起飞时间 到达时间 机型 票价\n");
	for (int i = 1; i <= L.length; i++)
		printf("%s %s %s %s %s %s %s %d\n", L.sl[i].keys,
		       L.sl[i].others.start, L.sl[i].others.end, L.sl[i].others.sche,
		       L.sl[i].others.time1, L.sl[i].others.time2, L.sl[i].others.mode1,
		       L.sl[i].others.price);
	serachcon(L); 			//调用查询函数 
}
1.问题描述 该设计要求对飞机航班信息进行排序查找。可按航班的航班号、起点站、终点站、起飞时间以及到达时间等信息进行查询。 2.扩展功能: ①能够在起点站与终点站相同的航班信息中筛选出票价最低及飞行时间最短的航班,并显示; ②能够不断添加新的航班信息; ③能够检验输入时间的合法性。 3.任务要求 对于本设计,可采用基数排序法对一组具有结构特点的飞机航班号进行排序,利用二分查找法对排好序的航班记录按航班号实现快速查找,按其他次关键字的查找可采用最简单的顺序查找方法进行,因此他们用得较少。 每个航班记录包括八项,分别是:航班号、起点站、终点站、班期、起飞时间、到达时间、飞机型号以及票价等,假设航班信息表(8条记录) 航班号 起点站 终点站 班期 起飞时间 到达时间 机型 票价 CA1544 合肥 北京 1.2.4.5 1055 1240 733 960 MU5341 上海 广州 每日 1420 1615 M90 1280 CZ3869 重庆 深圳 2.4.6 0855 1035 733 1010 MU3682 桂林 南京 2.3.4.6.7 2050 2215 M90 1380 HU1836 上海 北京 每日 0940 1120 738 1250 CZ3528 成都 厦门 1.3.4.5.7 1510 1650 CRJ 1060 MU4594 昆明 西安 1.3.5.6 1015 1140 328 1160 SC7425 青岛 海口 1.3.6 1920 2120 DH4 1630 其中航班号一项的格式为: K0 K1 K2 K3 K4 K5 C Z 3 8 6 9 其中K0K1的输入值是航空公司的别称,用两个大写字母标示,后4位为航班号,这种航班号关键字可分成两段,即字母数字。其余七项输入内容因为不涉及本设计的核心,因此除了票价为数值型外,均定义为字符串即可。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

比特冬哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值