第一次模拟项目,利用AVL树的航空管理系统

tree.h

#ifndef _TREE_H_
#define _TREE_H_

#include <stdio.h>
#include <stdlib.h>

#define MAX(a, b) ({ \
		typeof(a) _a = a; \
		typeof(b) _b = b; \
		(void)(&_a == &_b);\
		_a > _b? _a : _b; \
		})

typedef int tn_datatype;

typedef struct _tree_node
{
	int flight;//航班班次
	int take_off;//起飞时间
	int fall;//降落时间
	char start; //出发地点
	char bourn;//目的地
	int  num; //余票数
	int  money;//票价
	int high;//二叉树高度

	struct _tree_node *lchild;
	struct _tree_node *rchild;
}treenode, *linktree;

linktree avl_insert(linktree root, linktree new);
linktree avl_remove(linktree root, tn_datatype data);

linktree avl_rotate_left (linktree root);
linktree avl_rotate_right(linktree root);
linktree avl_rotate_leftright(linktree root);
linktree avl_rotate_rightleft(linktree root);
linktree find_tree(int data, linktree root);
linktree show_tree(linktree root);//打印

static int height(linktree root)
{
	return root==NULL ? 0 : root->high;
}

static linktree new_node(int flight)
{
	linktree new = malloc(sizeof(treenode));
	if(new != NULL)
	{
		new->flight = flight;
		new->high = 1;
		new->lchild = NULL;
		new->rchild = NULL;
 		new->num = 150; 
 		new->money = 2000;
	}
	return new;
}

#endif




tree.c

#include "tree.h"

linktree avl_rotate_right(linktree root)
{
	linktree tmp = root->lchild;
	root->lchild = tmp->rchild;
	tmp->rchild = root;
	
	root->high = MAX(height(root->lchild), height(root->rchild)) + 1;
	tmp->high = MAX(height(tmp->lchild), root->high) + 1;

	return tmp;
}


linktree avl_rotate_left(linktree root)
{
	linktree tmp = root->rchild;
	root->rchild = tmp->lchild;
	tmp->lchild = root;
	
	root->high = MAX(height(root->lchild), height(root->rchild)) + 1;
	tmp->high = MAX(root->high, height(tmp->rchild)) + 1;

	return tmp;
}

linktree avl_rotate_leftright(linktree root)
{
	root->lchild = avl_rotate_left(root->lchild);
	return avl_rotate_right(root);
}

linktree avl_rotate_rightleft(linktree root)
{
	root->rchild = avl_rotate_right(root->rchild);
	return avl_rotate_left(root);
}

linktree avl_insert(linktree root, linktree new)
{
	if(root == NULL)
		return new;


	if(new->flight < root->flight)
		root->lchild = avl_insert(root->lchild, new);
	else if(new->flight > root->flight)
		root->rchild = avl_insert(root->rchild, new);
	else
	{
		printf("根据《中华人民共和国航空安全条例》,所有民航飞机\n");
		printf("必须拥有独立编号,%d号飞机已存在,不能重复编号\n", new->flight);
	}


	if(height(root->lchild) - height(root->rchild) == 2)
	{
		if(new->flight < root->lchild->flight)
			root = avl_rotate_right(root);
		else if(new->flight > root->lchild->flight)
			root = avl_rotate_leftright(root);
	}

	else if(height(root->rchild) - height(root->lchild) == 2)
	{
		if(new->flight > root->rchild->flight)
			root = avl_rotate_left(root);
		else if(new->flight < root->rchild->flight)
			root = avl_rotate_rightleft(root);
	}


	root->high = MAX(height(root->lchild), height(root->rchild)) + 1;
	return root;
}

linktree avl_remove(linktree root, tn_datatype flight)
{
	if(root == NULL)
		return NULL;

	if(flight < root->flight)
		root->lchild = avl_remove(root->lchild, flight);
	else if(flight > root->flight)
		root->rchild = avl_remove(root->rchild, flight);
	else
	{
		linktree p;

		if(root->lchild != NULL)
		{
			for(p=root->lchild; p->rchild!=NULL; p=p->rchild){;}
			root->flight = p->flight;
			root->lchild = avl_remove(root->lchild, p->flight);
		}
		else if(root->rchild != NULL)
		{
			for(p=root->rchild; p->lchild!=NULL; p=p->lchild){;}
			root->flight = p->flight;
			root->rchild = avl_remove(root->rchild, p->flight);
		}
		else
		{
			free(root);
			return NULL;
		}
	}

	if(height(root->lchild) - height(root->rchild) == 2)
	{
		if(height(root->lchild->rchild)-height(root->lchild->rchild) == 1)
			root = avl_rotate_leftright(root);
		else
			root = avl_rotate_right(root);
	}
	else if(height(root->rchild) - height(root->lchild) == 2)
	{
		if(height(root->rchild->lchild)-height(root->rchild->rchild) == 1)
			root = avl_rotate_rightleft(root);
		else
			root = avl_rotate_left(root);
	}

	root->high = MAX(height(root->lchild), height(root->rchild)) + 1;
	return root;
}

linktree find_tree(int data, linktree root)
{  
if(root == NULL) // 如果树为空,则直接返回 NULL
	{
		//printf("您所查找的航班已起飞\n");
		return NULL;
	}
	
	if(data < root->flight) // 如果比根节点小,则递归地去左孩子树找
		return find_tree(data, root->lchild);
	else if(data > root->flight) // 如果比根节点大,则递归地去右孩子树找
		return find_tree(data, root->rchild);
	else
	
	return root; // 如果不大不小,那 root 就刚好是要找的节点了!
}

linktree show_tree(linktree root)//进行中序遍历并打印
{
	if(root == NULL)
	return NULL;
    
	show_tree(root->lchild); // 1:递归访问左子树

	printf("航班编号:%d  ",root->flight);
	printf("起飞地点:%c  ",root->start);
	printf("目的地: %c  ",root->bourn);
	printf("起飞时间:%d时\n  ",root->take_off);
	printf("降落时间%d时    ",root->fall);
	printf("余票数:%d张    ",root->num);
	printf("票价:%d元/张   \n",root->money);
	printf("\n");
	
	show_tree(root->rchild); // 2:递归访问右子树

}


find_tree.h

#ifndef _FIND_TREE_H_
#define _FIND_TREE_H_

#include <stdio.h>
#include "tree.h"
#include <string.h>

linktree find_flight(linktree root,int com);//按航班编号查找
linktree inquire_bourn(linktree root,char com);
linktree inquire_take_off(linktree root,int com);
linktree inquire_flight(linktree root,int com);
void show_only(linktree root);//打印一个航班信息

#endif




find_tree.c

#include "find_tree.h"

/********************买票用*********************/
linktree find_flight(linktree root,int com)//按航班编号查找
{   
	if(root == 0)
		return root;
    
	if (root->flight == com)
    {   
    	show_only(root);
    	return root;
    }
    return find_flight(root->lchild, com); // 根节点的左子树 

	return find_flight(root->rchild, com); // 根节点的右子树
}


/*****************查询用**********************/
linktree inquire_bourn(linktree root,char com)//按目的地查找
{   
	
	if(root == NULL)
		return 0;
    if (root->bourn == com)
    {
    	show_only(root);
    } 

	inquire_bourn(root->lchild, com); // 根节点的左子树
	
	inquire_bourn(root->rchild, com); // 根节点的右子树
}

linktree inquire_take_off(linktree root,int com)//按出发时间查找
{   
	if(root == NULL)
		return 0;
	 
	if (root->take_off == com)
    {   
    	show_only(root);
    } 

	inquire_take_off(root->lchild, com); // 根节点的左子树

	inquire_take_off(root->rchild, com); // 根节点的右子树
}


linktree inquire_flight(linktree root,int com)//按航班编号查找
{   
	if(root == 0)
		return 0;

	if (root->flight == com)
    {
    	show_only(root);
    }

	inquire_flight(root->lchild, com); // 根节点的左子树 

	inquire_flight(root->rchild, com); // 根节点的右子树
}
void show_only(linktree root)
{
	printf("航班编号:%d  ",root->flight);
	printf("起飞地点:%c  ",root->start);
	printf("目的地: %c  ",root->bourn);
	printf("起飞时间:%d时\n  ",root->take_off);
	printf("降落时间%d时    ",root->fall);
	printf("余票数:%d张    ",root->num);
	printf("票价:%d元/张   \n",root->money);
	printf("\n");
}




main.c


#include <stdio.h>
#include "tree.h" 
#include "find_tree.h"

linktree aircraft(linktree root);
linktree manage(linktree root);
void return_ticket(linktree root);
void ticket(linktree root);
void by_ticket(linktree root);
void mode(linktree by_num);
void find_ticket(linktree root);

int main(int argc, char const *argv[])
{
	linktree root = NULL;
    root = aircraft(root);
	int n;
	while(1)
	{   
		printf("请按提示进行操作\n");
		printf("0:进入航班管理系统\n");
		printf("1:进入售票系统\n");
		scanf("%d", &n);
		printf("\n");
        
		if(n == 0)
		{  
			root = manage(root);
            show_tree(root);
		}
		else if(n == 1)
		{   
			ticket(root);
		}
		else
			printf("输入错误,请重新输入\n");
			printf("\n");
			continue;
	}
	return 0;
}

linktree aircraft(linktree root)
{
	for (int i = 0; i < 10; ++i)
	{
		linktree new = new_node(i+1);
		new->take_off = i;//起飞时间
		new->fall = i+5;//降落时间
		new->start = 'a'+i; //出发地点
		new->bourn = 'A'+i;//目的地
		root = avl_insert(root, new);
	}
}


linktree manage(linktree root)
{
	int num=0;
	int num_s;
	int n = 0;
	char n_s;
 	linktree new;

	printf("请输入管理员密码(000000)\n");
	scanf("%d",&num);
	if (num == 000000)
	{
		while(1)
		{   
			printf("0:添加航班  1:让飞机起飞   2:查看当前机场所有飞机  3:退出管理员系统\n");
			scanf("%d",&num_s);
			if (num_s == 0)
			{   
				printf("请输入航班编号\n");
				scanf("%d",&n);
				new = new_node(n);
                
                getchar();
				printf("请输入起飞地点\n");
				scanf("%c",&n_s);
				new->start = n_s;

				getchar();
				printf("请输入目的地\n");
				scanf("%c",&n_s);
				new->bourn = n_s;

				getchar();
				printf("请输入起飞时间\n");
				scanf("%d",&n);
				new->take_off = n;

				getchar();
				printf("请输入降落时间\n");
				scanf("%d",&n);
				new->fall = n;	

				root = avl_insert(root, new);
			}
			else if (num_s == 1)
			{   
				printf("请输入飞机编号\n");
				scanf("%d",&n);
				if (find_tree(n,root))
				{
					avl_remove(root,n);

					printf("              ✈ ✈ \n");
					printf("              ✈ ✈ ✈ \n");
					printf("              ✈ ✈ ✈ ✈ \n");
					printf("              ✈ ✈ ✈ ✈ ✈\n");
					printf("✈ ✈           ✈ ✈ ✈ ✈ ✈ ✈\n");
					printf("✈ ✈ ✈         ✈ ✈ ✈ ✈ ✈ ✈ ✈\n");
					printf("✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ \n");
					printf("✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈\n");
					printf("✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈\n");
					printf("✈ ✈ ✈         ✈ ✈ ✈ ✈ ✈ ✈ ✈ \n");
					printf("✈ ✈           ✈ ✈ ✈ ✈ ✈ ✈  \n");
					printf("              ✈ ✈ ✈ ✈ ✈ \n");
					printf("              ✈ ✈ ✈ ✈ \n");
					printf("              ✈ ✈ ✈ \n");
					printf("              ✈ ✈ \n");
					
					printf("%d号飞机飞走啦\n",n);
				}
				else
				{
					printf("本机场无此航班\n");
				}
			}
			else if (num_s == 2)
			{
				show_tree(root);
			}
			else if (num_s == 3)
			{
				break;
			}
		}
	}
	return root;
}


void ticket(linktree root)
{   
	int num;
    while(1)
    {
		printf("0:购票    1:退票    2查询    3:退出售票系统\n");
		scanf("%d",&num);

		if (num == 0)
		{   
			by_ticket(root);
		}
		else if (num == 1)
		{
			return_ticket(root);
		}
		else if (num == 2)
		{
			find_ticket(root);
		}
		else if(num == 3)
		{
			break;
		}
	}
	
}

void find_ticket(linktree root)
{
	char by;
	int num_s;
	int ticket_num;
    linktree by_num;

    printf("0:按编号查找航班  1:按目的地查找航班 \n");
	scanf("%d",&num_s);
	printf("\n");
	if(num_s == 0)
	{
		printf("请输入航班编号\n");
		scanf("%d",&num_s);
        
		printf("编号为%d的航班列表\n",num_s);

		inquire_flight(root,num_s);
	}
	else if(num_s == 1)
	{   
		getchar();
		printf("请输入目的地\n");
		scanf("%c",&by);
        
        printf("飞往%c地的航班列表\n",by);

		inquire_bourn(root,by);
	}
}

void by_ticket(linktree root)
{   
	char by;
	int num_s;
	int ticket_num;
    linktree by_num;

    printf("0:按编号查找航班  1:按目的地查找航班  2:按起飞时间查找航班\n");
	printf("\n");
    scanf("%d",&num_s);
    if (num_s == 1)
     {
     	printf("本机场航班可到 A——Z等国家及地区\n");
		printf("请输入目的地\n");
		scanf("%s",&by);
		if (by >= 'A' && by <= 'Z')
		{   
			printf("飞往%c的航班列表\n",by);
			inquire_bourn(root,by);

			printf("请输入选择的航班编号\n");
            scanf("%d",&num_s);

			by_num = find_tree(num_s,root);;
	        mode(by_num);
		}   
		else
		{   
			printf("飞机飞不拢你那个卡卡1\n");
		}
    } 
    else if (num_s==0)
    {   

    	printf("请输入航班编号\n");
    	scanf("%d",&num_s);
        
    	by_num = find_tree(num_s,root);
    	show_only(by_num);

    	mode(by_num);
    }
    else if(num_s==2)
    {   
    	int i;

    	printf("请输入航班起飞时间\n");
    	scanf("%d",&i);

    	printf("于%d的航班列表\n",i);
		inquire_take_off(root,i);

		printf("请输入选择的航班编号\n");
        scanf("%d",&num_s);

		by_num = find_tree(num_s,root);;
        mode(by_num);
    }
}

void return_ticket(linktree root)
{   
    int i = 0; 
	int flight_tiket;
    linktree by_num;

	printf("请出示的机票,并输入航班编号\n");
	scanf("%d",&flight_tiket);
	printf("请输入退票张数\n");
	scanf("%d",&i);

	by_num = find_flight(root,flight_tiket);

	if (by_num->num < 150)
	{
		by_num->num=by_num->num+i;
		printf("退票成功,购票金额会原路返回,请耐心等候\n");
	}
	else
	{
		printf("退票失败\n");
	}

}

void mode(linktree by_num)
{   
	int ticket_num;
	int i;
	printf("\n");
    printf("当前余票%d张\n",by_num->num);
    printf("请选择购票数\n");
    scanf("%d",&ticket_num);
 
    if (ticket_num<=150)
    {
    	printf("确认购买%c到%c的机票%d张吗?\n",\
    	by_num->start,by_num->bourn,ticket_num);

    	printf("0确认    1放弃\n");
	    scanf("%d",&i);

	    if(i==0)
	    {
	    	by_num->num=by_num->num-ticket_num;
	    	printf("您已经购得%c到%c的机票%d张\n",\
	    	by_num->start,by_num->bourn,ticket_num);
	    }
    }
    else
    {
    	printf("飞机没有这么多桌位哦!\n");

    }
    
     
}

 

    原文作者:AVL树
    原文地址: https://blog.csdn.net/qq_42723835/article/details/81320119
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞