1.10.课设实验-数据结构-查找-机票查询

题目:

使用C语言/C++设计关于机票查询的代码。

参考代码:

cpp 复制代码
#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;  
}

相关推荐
biyezuopinvip1 小时前
音频DSP技术与应用数字信号处理算法实验(论文)
算法·音视频·信号处理·代码·音频dsp技术·应用数字信号·处理算法实验
小妖6661 小时前
力扣(LeetCode)- 60. 排列序列
算法·leetcode·职场和发展
im_AMBER1 小时前
Leetcode 70 好数对的数目 | 与对应负数同时存在的最大正整数
数据结构·笔记·学习·算法·leetcode
小妖6661 小时前
力扣(LeetCode)- 74. 搜索二维矩阵
算法·leetcode·矩阵
Liangwei Lin1 小时前
洛谷 U311289 矩阵距离
线性代数·算法·矩阵
云和数据.ChenGuang4 小时前
Ascend C 核心技术特性
c语言·开发语言
Dev7z4 小时前
基于MATLAB数学形态学的边缘检测算法仿真实现
算法·计算机视觉·matlab
风筝在晴天搁浅11 小时前
代码随想录 718.最长重复子数组
算法
kyle~11 小时前
算法---回溯算法
算法