题目:
使用C语言/C++设计关于机票查询的代码。
参考代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100 // 定义系统最大容量
//机票信息结构体
typedef struct
{
//1.航班号
char flightNumber[10];
//2.出发地
char departure[20];
//3.目的地
char destination[20];
//4.价格
int price;
}Ticket;
//二叉树结点结构体
typedef struct TreeNode
{
//1.数据域:机票信息
Ticket ticket;
//2.左子树指针
struct TreeNode* left;
//3.右子树指针
struct TreeNode* right;
}TreeNode;
//定义队列结点结构体
typedef struct QueueNode
{
//1.机票信息
Ticket ticket;
//2.下一个结点指针
struct QueueNode* next;
}QueueNode;
//定义队列结构体
typedef struct
{
//1.队头指针
QueueNode* front;
//2.队尾指针
QueueNode* rear;
}Queue;
//全局查找表 - 按航班号排序的机票数组
Ticket ticketTable[MAX];
//当前机票数量
int ticketCount = 0;
/*-------------------------------------------赵旭文-------------------------------------------*/
// 初始化队列
void initQueue(Queue* q)
{
//1.队头置空
q->front = NULL;
//2.队尾置空
q->rear = NULL;
}
// 入队操作
void enqueue(Queue* q, Ticket ticket)
{
//1.分配新队列结点内存
QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
//2.存储机票信息
newNode->ticket = ticket;
//3.新结点next指针置空
newNode->next = NULL;
//4.判断
if (q->rear == NULL) {
/*4.1.如果队列为空*/
q->front = newNode; //队头指向新结点
q->rear = newNode; //队尾指向新结点
}
else /*4.2.队列不为空*/
{
q->rear->next = newNode; //当前队尾的next指向新结点
q->rear = newNode; //更新队尾为新结点
}
}
// 检查队列是否为空
int isQueueEmpty(Queue* q)
{
//队头为空表示队列为空
return q->front == NULL; /*为空时返回1即真,不为空时返回0即假*/
}
//出队列的函数
Ticket dequeue(Queue* q)
{
//1.获取队头机票信息
Ticket ticket = q->front->ticket;
//2.临时保存队头结点
QueueNode* temp = q->front;
//3.此时队头需要指向下一个结点
q->front = q->front->next;
//4.判断
if (q->front == NULL)
{
//如果此时队列变空,那么队尾也置空
q->rear = NULL;
}
//5.释放原队头结点内存
free(temp);
//6.返回机票信息
return ticket;
}
/*-------------------------------------------赵旭文-------------------------------------------*/
/*-------------------------------------------吴佳峻-------------------------------------------*/
//创建二叉树新结点的函数
TreeNode* createNode(Ticket ticket)
{
//1.分配新结点内存
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
//2.存储机票信息
newNode->ticket = ticket;
//3.左子树置空
newNode->left = NULL;
//4.右子树置空
newNode->right = NULL;
//5.返回新节点指针
return newNode;
}
//向二叉树插入结点的函数(按价格排序)
/*需要二叉树、要插入的结点*/
TreeNode* insertTree(TreeNode* root, Ticket ticket)
{
//1.如果树为空
if (root == NULL)
{
//创建新结点作为根结点
return createNode(ticket);
}
//2.此时树不为空,就需要从根结点开始比较
if ( ticket.price < root->ticket.price)
{
/*2.1.如果新机票价格小于当前结点,
递归插入左子树 */
root->left = insertTree( root->left, ticket);
}
else
{
/*2.2.如果新机票价格大于等于当前结点,
递归插入右子树*/
root->right = insertTree(root->right, ticket);
}
//3.返回当前结点指针,也就是最终的树
return root;
}
/*-------------------------------------------吴佳峻-------------------------------------------*/
/*-------------------------------------------黄黄-------------------------------------------*/
//显示机票信息的函数
void displayTicket(Ticket ticket)
{
//输出机票信息
printf("航班号: %s 出发地: %s 目的地: %s 价格: %d元\n",
ticket.flightNumber,
ticket.departure,
ticket.destination,
ticket.price);
}
//显示所有机票信息的函数
void displayAllTicket()
{
//循环遍历输出每一张机票信息
for( int i=0 ; i<ticketCount ; i++ )
{
displayTicket(ticketTable[i]);
}
}
// 二叉树中序遍历(按价格升序显示)
void inOrderTraversal(TreeNode* root)
{
//如果二叉树不为空(root初始为根结点)
if (root != NULL) {
//1.递归遍历左子树
inOrderTraversal(root->left);
//2.显示当前结点机票信息
displayTicket(root->ticket);
//3.递归遍历右子树
inOrderTraversal(root->right);
}
}
/*-------------------------------------------黄黄-------------------------------------------*/
/*-------------------------------------------青格勒-------------------------------------------*/
// 二分查找航班号
int binarySearchByFlightNumber(char* flightNumber) {
//1.左边界、右边界
int left = 0;
int right = ticketCount - 1;
//2.当搜索区间有效时循环
while (left <= right)
{
//3.计算中间位置
int mid = (left + right) / 2;
//4.比较航班号
int cmp = strcmp(ticketTable[mid].flightNumber, flightNumber);
//5.如果找到目标
if (cmp == 0)
{
//6.返回索引位置
return mid;
}
else if (cmp < 0)
{
//7.如果中间值小于目标值->调整左边界进入右部分查找
left = mid + 1;
}
else
{
//8.如果中间值大于目标值->调整右边界进入左部分查找
right = mid - 1;
}
}
//9.未找到返回-1
return -1;
}
//顺序查找目的地
void sequentialSearchByDestination(char* destination, Queue* resultQueue)
{
//1.遍历所有机票进行查找
for (int i = 0; i < ticketCount; i++)
{
//2.比较目的地,只要已有的机票的目的地与要查找的机票的目的地一样就入队列,无需管起点
if (strcmp(ticketTable[i].destination, destination) == 0)
{
enqueue(resultQueue, ticketTable[i]);
}
}
}
/*-------------------------------------------青格勒-------------------------------------------*/
/*-------------------------------------------黄黄-------------------------------------------*/
//初始化机票查找表的函数
void initTicketTable()
{
//1.初始化第一条机票记录
strcpy(ticketTable[0].flightNumber, "CA1234");
strcpy(ticketTable[0].departure, "北京");
strcpy(ticketTable[0].destination, "上海");
ticketTable[0].price = 680;
//2.初始化第二条机票记录
strcpy(ticketTable[1].flightNumber, "MU5678");
strcpy(ticketTable[1].departure, "上海");
strcpy(ticketTable[1].destination, "广州");
ticketTable[1].price = 920;
//3.初始化第三条机票记录
strcpy(ticketTable[2].flightNumber, "CZ9012");
strcpy(ticketTable[2].departure, "北京");
strcpy(ticketTable[2].destination, "深圳");
ticketTable[2].price = 1100;
//4.初始化第四条机票记录
strcpy(ticketTable[3].flightNumber, "HU3456");
strcpy(ticketTable[3].departure, "广州");
strcpy(ticketTable[3].destination, "成都");
ticketTable[3].price = 540;
//5.初始化第五条机票记录
strcpy(ticketTable[4].flightNumber, "MF7890");
strcpy(ticketTable[4].departure, "深圳");
strcpy(ticketTable[4].destination, "广州");
ticketTable[4].price = 1250;
//6.设置当前机票数量
ticketCount = 5;
//7.按航班号排序机票查找表(为二分查找做准备)->使用冒泡排序->按照升序排序
int i, j;
for (i = 0; i < ticketCount - 1; i++)
{
for (j = 0; j < ticketCount - 1 - i; j++)
{
if (strcmp(ticketTable[j].flightNumber, ticketTable[j + 1].flightNumber) > 0)
{
// 交换位置
Ticket temp = ticketTable[j];
ticketTable[j] = ticketTable[j + 1];
ticketTable[j + 1] = temp;
}
}
}
}
/*-------------------------------------------黄黄-------------------------------------------*/
int main()
{
//1.初始化机票查找表并打印
initTicketTable();
displayAllTicket();
printf("=========================================================== \n");
//2.构建二叉树 - 按价格排序
/*2.1.创建空树*/
TreeNode* priceTree = NULL;
/*2.2.插入每个机票到二叉树*/
for (int i = 0; i < ticketCount; i++)
{
priceTree = insertTree(priceTree, ticketTable[i]);
}
//3.声明结果队列
Queue searchResults;
//4.初始化队列
initQueue(&searchResults);
//5.定义变量记录用户选项
int choice;
//6.搜索关键字缓冲区
char searchKey[20];
//7.界面
printf("=== 机票查询系统 ===\n");
do
{
//8.显示菜单
printf("\n请选择查询方式:\n");
printf("1. 按航班号查询(二分查找)\n");
printf("2. 按目的地查询(顺序查找)\n");/*思路:把目的地一样的行程入队列,之后再依次出队列打印*/
printf("3. 按价格排序显示(二叉树中序遍历)\n");
printf("4. 退出系统\n");
printf("请输入选择(1-4): ");
//9.读取用户选择
scanf("%d", &choice);
//10.进行对应操作
switch(choice)
{
case 1:
{
//输入航班号
printf("请输入航班号: ");
//读取航班号
scanf("%s", searchKey);
//进行二分查找
int index = binarySearchByFlightNumber(searchKey);
//判断
if (index != -1)
{
//显示找到的机票
printf("\n找到航班信息:\n");
displayTicket(ticketTable[index]);
}
else
{
printf("未找到该航班号对应的机票\n");
}
break;
}
case 2:
{
//输入目的地
printf("请输入目的地: ");
//读取目的地
scanf("%s",searchKey);
//初始化结果队列
initQueue(&searchResults);
//顺序查找
sequentialSearchByDestination(searchKey, &searchResults);
//判断
if ( isQueueEmpty(&searchResults) )
{
//此时结果队列即目的地队列为空
printf("未找到前往该目的地的航班\n");
}
else
{
//此时结果队列即目的地队列不为空
printf("\n找到以下航班:\n");
while( !isQueueEmpty(&searchResults) )
{
//从队列取出结果
Ticket t = dequeue(&searchResults);
//显示机票信息
displayTicket(t);
}
}
break;
}
case 3:
{
printf("\n按价格排序的航班信息:\n");
//中序遍历二叉树
inOrderTraversal(priceTree);
break;
}
case 4:
{
printf("谢谢使用,再见!\n");
break;
}
default:
printf("无效选择,请重新输入!\n");
}
} while (choice != 4); // 循环直到用户选择退出
//11.程序正常结束
return 0;
}
5432

被折叠的 条评论
为什么被折叠?



