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");
}
}