二叉树演示系统

函数列表
对二叉树进行构造、销毁、创建、清空、判空、求深度、前中后序遍历、按层遍历,获得根结点、获得结点、结点赋值、获得双亲结点、获得左孩子结点、获得右孩子结点、获得左兄弟结点、获得右兄弟结点、插入子树和删除子树数据加载以及数据保存等操作。此外,为实现多树管理,还需定义多表遍历函数和线性表查询函数,为实现这些操作,需要对功能函数进行如下的定义。
(1)InitBiTree(T):初始条件是二叉树T不存在;操作结果是构造空二叉树T。
(2)DestroyBiTree(T):初始条件是二叉树T已存在;操作结果是销毁二叉树T。
(3)CreateBiTree(T,definition):初始条件是definition 给出二叉树T的定义;操作结果是按definition构造二叉树T。
(4)ClearBiTree (T):初始条件是二叉树T存在; 操作结果是将二叉树T清空。
(5)BiTreeEmpty(T):初始条件是二叉树T存在;操作结果是若T为空二叉树则返回TRUE,否则返回FALSE。
(6)BiTreeDepth(T):初始条件是二叉树T存在;操作结果是返回T的深度。
(7)Root(T):初始条件是二叉树T已存在;操作结果是返回T的根。
(8)Value(T,e):初始条件是二叉树T已存在,e是T中的某个结点;操作结果是返回e的值。
(9)Assign(T,&e,value):初始条件是二叉树T已存在,e是T中的某个结点;操作结果是结点e赋值为value。
(10)Parent(T,e) :初始条件是二叉树T已存在,e是T中的某个结点;操作结果是若e是T的非根结点,则返回它的双亲结点指针,否则返回NULL。
(11)LeftChild(T,e):初始条件是二叉树T存在,e是T中某个节点;操作结果是返回e的左孩子结点指针。若e无左孩子,则返回NULL。
(12)RightChild(T,e):初始条件是二叉树T已存在,e是T中某个结点;操作结果是返回e的右孩子结点指针。若e无右孩子,则返回NULL。
(13)LeftSibling(T,e):初始条件是二叉树T存在,e是T中某个结点;操作结果是返回e的左兄弟结点指针。若e是T的左孩子或者无左兄弟,则返回NULL。
(14)RightSibling(T,e):初始条件是二叉树T已存在,e是T中某个结点;操作结果是返回e的右兄弟结点指针。若e是T的右孩子或者无有兄弟,则返回NULL。
(15)InsertChild(T,p,LR,c):初始条件是二叉树T存在,p指向T中的某个结点,LR为0或1,,非空二叉树c与T不相交且右子树为空;操作结果是根据LR为0或者1,插入c为T中p所指结点的左或右子树,p 所指结点的原有左子树或右子树则为c的右子树。
(16)DeleteChild(T.p.LR):初始条件是二叉树T存在,p指向T中的某个结点,LR为0或1。 操作结果是根据LR为0或者1,删除c为T中p所指结点的左或右子树。
(17)PreOrderTraverse(T,Visit()):初始条件是二叉树T存在,Visit是对结点操作的应用函数;操作结果:先序遍历t,对每个结点调用函数Visit一次且一次,一旦调用失败,则操作失败。
(18)InOrderTraverse(T,Visit)):初始条件是二叉树T存在,Visit是对结点操作的应用函数;操作结果是中序遍历t,对每个结点调用函数Visit一次且一次,一旦调用失败,则操作失败。
(19)PostOrderTraverse(T,Visit)):初始条件是二叉树T存在,Visit是对结点操作的应用函数;操作结果是后序遍历t,对每个结点调用函数Visit一次且一次,一旦调用失败,则操作失败。
(20)LevelOrderTraverse(T,Visit)):初始条件是二叉树T存在,Visit是对结点操作的应用函数;操作结果是层序遍历t,对每个结点调用函数Visit一次且一次,一旦调用失败,则操作失败。
(21)Status SaveBiTree(BiTree T,char *filename); //保存二叉树,按先序序列,无空格进行保存,‘#’代表结点为空
(22)BiTree ReadBiTree(BiTree *T,char *filenarne,int mode);//读取二叉树,按先序序列,无空格进行读取,‘#’代表结点为空
(23)BiTree FindNode(BiTree T, int e);//查找节点标记为e的结点,返回结点指针
(24)TreeList CopyBitree(BiTree T);//根据二叉树T创建一个相同结构和值的树,返回根节点
(25)TreeList TreeTrabverse(TreeList Ts);//遍历管理链表,返回尾节点指针
(26)TreeList Find(TreeList Ts, int mode, char *treename, BiTree *T);//查找指定名称的二叉树,将二叉树根节点指针赋给T

代码

/* BiTree On List Structure */
#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
#include<string.h>

/*函数执行状态结果*/
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASTABLE -1
#define OVERFLOW -2
#define MAXQSIZE 100

typedef int Status;
typedef char ElemType; //数据元素类型定义

typedef struct TreeElemType{
	int num;
	ElemType value;
}TreeElemType;

typedef struct BiTNode { //二叉树结点结构,包括数据域,左右孩子指针
	TreeElemType data;
	struct BiTNode *lchild,*rchild; //左右孩子指针
}BiTNode, *TNode, *BiTree;

typedef struct Tree { //用于管理二叉树的链表结点结构,保存二叉树名称,根节点地址
	char name[20];
	BiTree Root;
	struct Tree *next;
}Tree, *TreeList;
int TreeNum = 0; //使用全局变量保存二叉树数目

Status InitBiTree(BiTree *T);//构造空二叉树T。
Status DestroyBiTree(BiTree T);//销毁二叉树T。
Status CreateBiTree(BiTree T, char *String);//String保存输入字符,按先序序列,无空格进行输入,‘#’代表结点为空。根据输入字符进行二叉树创建
Status ClearBiTree(BiTree T);//将二叉树T清空。
Status BiTreeEmpty(BiTree T);//若T为空二叉树则返回TRUE,否则返回FALSE。
int BiTreeDepth(BiTree T);//返回T的深度。
char Root(BiTree T);//返回T的根。
char Value(BiTree T, int e);//e是T中的某个结点;返回e的值。
Status Assign(BiTree T, int e, ElemType value);//e是T中的某个结点,结点e赋值为value。
BiTree Parent(BiTree T, int e);//获得双亲结点
BiTree LeftChild(BiTree T, int e);//返回e的左孩子结点指针
BiTree RightChild(BiTree T, int e);//返回e的右孩子结点指针
BiTree LeftSibling(BiTree T, int e);//返回e的左兄弟结点指针
BiTree RightSibling(BiTree T, int e);//返回e的右兄弟结点指针
Status InsertChild(BiTree T, BiTree P, int LR, BiTree C);//插入子树
Status DeleteChild(BiTree T, BiTree P, int LR);//删除子树
Status PreOrderTraverse(BiTree T);//前序遍历
Status InOrderTraverse(BiTree T);//中序遍历
Status PostOrderTraverse(BiTree T);//后序遍历
Status LevelOrderTraverse(BiTree T);//按层遍历
Status SaveBiTree(BiTree T,char *filename); //保存二叉树,按先序序列,无空格进行保存,‘#’代表结点为空
BiTree ReadBiTree(BiTree *T,char *filenarne,int mode);//读取二叉树,按先序序列,无空格进行读取,‘#’代表结点为空
BiTree FindNode(BiTree T, int e);//查找节点标记为e的结点,返回结点指针
TreeList CopyBitree(BiTree T);//根据二叉树T创建一个相同结构和值的树,返回根节点
TreeList TreeTrabverse(TreeList Ts);//遍历管理链表,返回尾节点指针
TreeList Find(TreeList Ts, int mode, char *treename, BiTree *T);//查找指定名称的二叉树,将二叉树根节点指针赋给T

Status InitBiTree(BiTree *T) {//构造空二叉树T。
	(*T) = (BiTree)malloc(sizeof(BiTNode));
	if ((*T) == NULL) exit(OVERFLOW); //存储分配失败
	(*T)->data.num = 0;
	(*T)->lchild = (*T)->rchild = NULL;
	return OK;
}

Status DestroyBiTree(BiTree T) {//销毁二叉树
	int top = -1;
	TNode stack[100], p, q;
	p = T->lchild, q = T->rchild;		//p赋值T的左孩子
	if (p == NULL ) { //T左孩子为空
		free(T);	//释放T的空间
		return OK;
	}
	if(T->lchild) stack[++top] = T->lchild; //T左孩子不为空,栈顶元素赋值为T左孩子
	while (top>-1)
	{
		p = stack[top--];//若栈不为空,p赋值为栈顶元素,栈顶元素出栈,栈顶指针左移
		q = p;
		if (p->rchild) stack[++top] = p->rchild; //p所指结点右孩子不为空,栈顶指针右移,p所指结点右孩子入栈
		if (p->lchild) stack[++top] = p->lchild;//p所指结点左孩子不为空,栈顶指针右移,p所指结点左孩子入栈
		free(q);//释放结点p
	}
	free(T);
	return OK;
}

Status CreateBiTree(BiTree T, char *String) {//用先序序列建立二叉链表
	//String保存输入字符,按先序序列,无空格进行输入,‘#’代表结点为空。根据输入字符进行二叉树创建
	BiTree stack[100], Tr, Tq;
	int i = 1, top = 0, n = 1;
	T->data.num = 0;
	T->lchild = T->rchild = NULL;
	if (String[0] == '#') {//若树根不存在,返回不执行
		return INFEASTABLE;
	}

	Tr = (BiTree)malloc(sizeof(BiTNode));//为当前指针分配存储空间
	Tr->data.value = String[0];	//为当前节点赋值
	Tr->data.num = 1;	//为当前节点打标记
	Tr->lchild = Tr->rchild = NULL;

	T->lchild = Tr;	//将当前树根结点指针赋给*T的左孩子
	stack[top] = Tr;//根节点入栈
	while (String[i] != '\n') { //输入字符还未读取完
		if (String[i] != '#') {//读入字符不为空‘#’
			Tr = (BiTree)malloc(sizeof(BiTNode));
			Tr->data.value = String[i];
			Tr->data.num = n+1;
			Tr->lchild = Tr->rchild = NULL;
			while (stack[top]->rchild != NULL ) top--;//退回至子节点未满的结点上
			if (top <= -1) return FALSE;
			Tq = stack[top];//栈顶元素赋值给Tq
			stack[++top] = Tr;//当前元素进栈
			if (String[i - 1] != '#') Tq->lchild = Tr;
			else {
				Tq->rchild = Tr;
			}
			n++;
		}
		else {//读入字符为空‘#’
			while (stack[top]->rchild != NULL) top--;
			Tq = stack[top];
			if (String[i - 1] != '#')//若前一字符不为空,则将栈顶元素左孩子赋空
				Tq->lchild = NULL;
			else {//前一字符为空,将栈顶元素右孩子赋空值,栈顶元素退栈,栈顶指针左移
				Tq->rchild = NULL;
				top--;
			}
		}
		i++;//下一个字符
	}
	T->data.num = n;	//头结点保存二叉树结点数
	return OK;
}

Status ClearBiTree(BiTree T){//清空二叉树,保留头结点,释放其余空间
	int top = -1;
	TNode stack[100], p, q;
	p = T->lchild, q = T->rchild;		//p赋值T的左孩子
	if (p == NULL) { //T左孩子为空,无需操作,二叉树为空二叉树
		return OK;
	}
	if (T->lchild) stack[++top] = T->lchild; //T左孩子不为空,栈顶元素赋值为T左孩子
	while (top > -1)
	{
		p = stack[top--];//若栈不为空,p赋值为栈顶元素,栈顶元素出栈,栈顶指针左移
		q = p;
		if (p->rchild) stack[++top] = p->rchild; //p所指结点右孩子不为空,栈顶指针右移,p所指结点右孩子入栈
		if (p->lchild) stack[++top] = p->lchild;//p所指结点左孩子不为空,栈顶指针右移,p所指结点左孩子入栈
		free(q);//释放结点p
	}
	T->data.num = 0;
	T->lchild = NULL;
	return OK;
}

Status BiTreeEmpty(BiTree T) {//判断二叉树是否为空
	if (T->data.num == 0) return TRUE;//二叉树结点数为0,为空二叉树,返回TRUE
	return FALSE;
}

int BiTreeDepth(BiTree T) {//计算二叉树的深度并返回深度值
	int i, j;
	if (T == NULL) return 0;//递归出口
	i = BiTreeDepth(T->lchild);//递归调用求深度
	j = BiTreeDepth(T->rchild);
	if (i > j) return(i + 1);
	return(j + 1);
}

char Root(BiTree T) {//找到树的根
	if(T->lchild) return T->lchild->data.num;
	return ERROR;
}

char Value(BiTree T, int e) {//若e是二叉树某个结点,返回e的值
	int top = 0;
	BiTree stack[100], Tp;
	stack[top] = T->lchild;
	while (top>-1){
		Tp = stack[top--];	//核对栈顶元素,栈顶元素退栈
		if (Tp->data.num == e) {//查找到,返回元素值
			return Tp->data.value;
		}
		if (Tp->rchild) stack[++top] = Tp->rchild;//当前节点不匹配,若当前节点右孩子不空,当前节点右孩子入栈
		if (Tp->lchild) stack[++top] = Tp->lchild;//当前节点不匹配,若当前节点左孩子不空,当前节点左孩子入栈
	}
	return ERROR;//未查找到,返回ERROR
}

Status Assign(BiTree T, int e, ElemType v) {//给结点e赋值为value
	int top = 0;
	BiTree stack[100], Tp;
	stack[top] = T->lchild;
	while (top > -1) {
		Tp = stack[top--];	//核对栈顶元素,栈顶元素退栈
		if (Tp->data.num == e) {//查找到,退出循环
			break;
		}
		if (Tp->rchild) stack[++top] = Tp->rchild;//当前节点不匹配,若当前节点右孩子不空,当前节点右孩子入栈
		if (Tp->lchild) stack[++top] = Tp->lchild;//当前节点不匹配,若当前节点左孩子不空,当前节点左孩子入栈
	}
	if (Tp->data.num != e) return ERROR;//退出循环后,若当前节点标记不等于e,则未查找到该元素,返回ERROR
	Tp->data.value = v;//查找到该节点,进行赋值
	return OK;
}

BiTree Parent(BiTree T, int e) {//查找节点e,返回其双亲结点
	int top = 0;
	BiTree stack[100], Tp;
	stack[top] = T->lchild;//根节点进栈
	while (top > -1) {
		Tp = stack[top--];//栈顶元素赋值给Tp,栈顶元素退栈
		if (Tp->lchild) {//检查Tp左孩子是否匹配
			if (Tp->lchild->data.num == e) return Tp;//查找到节点,返回双亲结点
			stack[++top] = Tp->lchild;//不匹配,左孩子进栈
		}
		if (Tp->rchild) {//检查Tp右孩子是否匹配
			if (Tp->rchild->data.num == e) return Tp;//查找到节点,返回双亲结点
			stack[++top] = Tp->rchild;//不匹配,右孩子进栈
		}
	}
	return NULL;//退出循环后,未查找到节点e,返回NULL
}

BiTree LeftChild(BiTree T, int e) {//返回e的左孩子结点指针
	int top = 0;
	BiTree stack[100], Tp;
	stack[top] = T->lchild;//根节点进栈
	while (top > -1) {
		Tp = stack[top--];//栈顶元素赋值给Tp,栈顶元素退栈
		if (Tp->data.num == e) return Tp->lchild;//查找到节点e,返回其左孩子
		if (Tp->rchild) stack[++top] = Tp->rchild;//未查找到,当前节点右孩子不空,右孩子进栈
		if (Tp->lchild) stack[++top] = Tp->lchild;//未查找到,当前节点左孩子不空,左孩子进栈
	}
	if (top <= -1) return NULL;//退出循环后,未查找到节点e,返回NULL
}

BiTree RightChild(BiTree T, int e) {//返回e的右孩子结点指针
	int top = 0;
	BiTree stack[100], Tp;
	stack[top] = T->lchild;//根节点进栈
	while (top > -1) {
		Tp = stack[top--];//栈顶元素赋值给Tp,栈顶元素退栈
		if (Tp->data.num == e) return Tp->rchild;//查找到节点e,返回其右孩子
		if (Tp->rchild) stack[++top] = Tp->rchild;//未查找到,当前节点右孩子不空,右孩子进栈
		if (Tp->lchild) stack[++top] = Tp->lchild;//未查找到,当前节点左孩子不空,左孩子进栈
	}
	if (top <= -1) return NULL;//退出循环后,未查找到节点e,返回NULL
}

BiTree LeftSibling(BiTree T, int e) {//返回e的左兄弟结点指针
	int top = 0;
	BiTree stack[100], Tp;
	stack[top] = T->lchild;//根节点进栈
	if (T->lchild->data.num == e) return NULL;//所查找节点为根节点,返回NULL
	while (top > -1) {
		Tp = stack[top--];//栈顶元素赋值给Tp,栈顶元素退栈
		if (Tp->rchild) {//若右子树存在
			if (Tp->rchild->data.num == e) {//若右子树为所查找节点
				if (Tp->lchild) return Tp->lchild;//左子树存在,返回左子树
				else return NULL;
			}
			stack[++top] = Tp->rchild;//Tp右子树不是所查找节点,右子树进栈
		}
		if (Tp->lchild) {//若左子树存在
			if (Tp->lchild->data.num == e) return NULL;//左子树为所查找节点,返回NULL
			stack[++top] = Tp->lchild;//左子树不是所查找节点,左子树进栈
		}
	}
	if (top <= -1) return NULL;//未查找到,返回NULL
}

BiTree RightSibling(BiTree T, int e) {//返回e的右兄弟结点指针
	int top = 0;
	BiTree stack[100], Tp;
	stack[top] = T->lchild;//根节点进栈
	if (T->lchild->data.num == e) return NULL;//所查找节点为根节点,返回NULL
	while (top > -1) {
		Tp = stack[top--];//栈顶元素赋值给Tp,栈顶元素退栈
		if (Tp->lchild) {//若左子树存在
			if (Tp->lchild->data.num == e) {//若左子树为所查找节点
				if (Tp->rchild) return Tp->rchild;//右子树存在,返回右子树
				else return NULL;
			}
			stack[++top] = Tp->rchild;//Tp右子树不是所查找节点,右子树进栈
		}
		if (Tp->rchild) {//若右子树存在
			if (Tp->rchild->data.num == e) return NULL;//右子树为所查找节点,返回NULL
			stack[++top] = Tp->rchild;//右子树不是所查找节点,右子树进栈
		}
	}
	if (top <= -1) return NULL;//未查找到,返回NULL
}

Status InsertChild(BiTree T, BiTree P, int LR, BiTree C) {//插入子树
	int i = 0,top = -1;
	BiTree stack[100], Tp;
	if (T->data.num == 0) return INFEASTABLE;	//二叉树T为空
	if (LR == 0) {
		C->rchild = P->lchild;
		P->lchild = C;
		stack[++top] = T->lchild;//根节点进栈
		while (top>-1) {
			Tp = stack[top--];
			i++;
			Tp->data.num = i;
			if (Tp->rchild) stack[++top] = Tp->rchild;
			if (Tp->lchild) stack[++top] = Tp->lchild;
		}
		T->data.num = i;
		return OK;
	}
	if (LR == 1) {
		C->rchild = P->rchild;
		P->rchild = C;
		stack[++top] = T->lchild;//根节点进栈
		while (top > -1) {
			Tp = stack[top--];
			i++;
			Tp->data.num = i;
			if (Tp->rchild) stack[++top] = Tp->rchild;
			if (Tp->lchild) stack[++top] = Tp->lchild;
		}
		T->data.num = i;
		return OK;
	}
}

Status DeleteChild(BiTree T, BiTree P, int LR) {//删除子树
	BiTree stack[100], Tp, Tq;
	int top = -1,i=0;
	if (T->lchild == NULL) return INFEASTABLE;	//二叉树为空
	i = T->data.num;
	if (LR == 0) {//删除P的左子树
		Tp = P->lchild;
		if (Tp == NULL) return ERROR;//左孩子为空,返回ERROR
		P->lchild = NULL;
		stack[++top] = Tp;
		while (top>-1){
			Tp = stack[top--];
			Tq = Tp;
			if (Tp->rchild) stack[++top] = Tp->rchild;
			if (Tp->lchild) stack[++top] = Tp->lchild;
			free(Tq);
			i--;
		}
		T->data.num = i;
		return OK;
	}

	if (LR == 1) {//删除P的右子树
		Tp = P->rchild;
		if (Tp == NULL) return ERROR;//左孩子为空,返回ERROR
		P->rchild = NULL;
		stack[++top] = Tp;
		while (top > -1) {
			Tp = stack[top--];
			Tq = Tp;
			if (Tp->rchild) stack[++top] = Tp->rchild;
			if (Tp->lchild) stack[++top] = Tp->lchild;
			free(Tq);
			i--;
		}
		T->data.num = i;
		return OK;
	}
}

Status PreOrderTraverse(BiTree T) {//前序遍历,非递归实现
	BiTree stack[100], Tp;
	int top = -1;
	if (T == NULL) return ERROR;
	stack[++top] = T;//根节点入栈
	while (top>-1){//栈不空
		Tp = stack[top--];//栈顶元素赋值给Tp,栈顶元素出栈
		printf("%d: %c  ", Tp->data.num, Tp->data.value);
		if (Tp->rchild) stack[++top] = Tp->rchild;//栈顶元素右孩子不空,右孩子进栈
		if (Tp->lchild) stack[++top] = Tp->lchild;//栈顶元素左孩子不空,左孩子进栈
	}
	return OK;
}

Status InOrderTraverse(BiTree T) {//中序遍历,递归实现
	if (T != NULL) {
		InOrderTraverse(T->lchild);
		printf("%d: %c  ", T->data.num, T->data.value);
		InOrderTraverse(T->rchild);
		return OK;
	}
	return 0;
}

Status PostOrderTraverse(BiTree T) {//后序遍历,递归实现
	if (T != NULL) {
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		printf("%d: %c  ", T->data.num, T->data.value);
		return OK;
	}
	return 0;
}

Status LevelOrderTraverse(BiTree T) {//按层遍历,利用队列,非递归实现
	int front = 0, rear = 0;
	BiTree SqQueue[MAXQSIZE], Tp;
	if (T == NULL) return ERROR;
	SqQueue[rear] = T;//根节点入队
	rear = ++rear % MAXQSIZE;
	while ((rear-front+MAXQSIZE)%MAXQSIZE)//若队列不空
	{
		Tp = SqQueue[front];//队头元素赋值给Tp
		printf("%d: %c  ", Tp->data.num, Tp->data.value);//访问队头元素
		if (Tp->lchild){ 
			SqQueue[rear] = Tp->lchild;//队头元素左孩子入队
			rear = ++rear % MAXQSIZE;
		}
		if (Tp->rchild){
			SqQueue[rear] = Tp->rchild;//队头元素右孩子入队
			rear = ++rear % MAXQSIZE;
		} 
		front = ++front % MAXQSIZE;//队头元素出队
	}
	return OK;
}

Status SaveBiTree(BiTree T, char *filename) { //保存二叉树,按先序序列,无空格进行保存,‘#’代表结点为空
	FILE *fp;
	BiTree stack[100], Tp;
	int top = -1;
	if ((fp = fopen(filename, "w")) == NULL) {
		printf("文件打开失败!\n");
		return ERROR;
	}
	if (T == NULL) {//空树,保存一个‘#'
		fputc('#', fp);
		fclose(fp);
		return OK;
	}
	printf("保存字符序列为: ");
	stack[++top] = T;//根节点进栈
	while (top>-1){//栈不空
		Tp = stack[top--];//栈顶元素赋值给Tp
		if (Tp) {//Tp不为空
			fputc(Tp->data.value, fp);//Tp所指结点值写入文件
			putchar(Tp->data.value);//输出节点值
			stack[++top] = Tp->rchild;//Tp所指结点右孩子进栈
			stack[++top] = Tp->lchild;//Tp所指结点左孩子进栈
		}
		else{//Tp为空
			fputc('#', fp);//写入一个‘#’
			putchar('#');
		}
	}
	printf("\n");
	fclose(fp);
	return OK;
}

BiTree ReadBiTree(BiTree *T,char *filenarne,int mode) {//读取二叉树,按先序序列,无空格进行读取,‘#’代表结点为空
	FILE *fp;
	BiTree stack[100], Tp, Tr;
	int top = -1, i = 0, n = 1;
	char tree[100];
	if ((fp = fopen(filenarne, "r")) == NULL) {
		printf("文件打开失败\n");
		return NULL;
	}
	printf("读入字符序列为: ");
	while ((tree[i] = fgetc(fp))!= EOF)
	{
		putchar(tree[i]);
		i++;
	}
	tree[i] = '\n';
	putchar(tree[i]);
	i = 1;
	
	if(mode == 2) (*T) = (BiTree)malloc(sizeof(BiTNode));
	(*T)->data.num = 0;
	(*T)->lchild = (*T)->rchild = NULL;
	if (tree[0] == '#') {//若树根不存在,创建空树
		fclose(fp);
		return *T;
	}

	Tr = (BiTree)malloc(sizeof(BiTNode));//为当前指针分配存储空间
	Tr->data.value = tree[0];	//为当前节点赋值
	Tr->data.num = 1;	//为当前节点打标记
	Tr->lchild = Tr->rchild = NULL;

	(*T)->lchild = Tr;	//将当前树根结点指针赋给T的左孩子
	stack[++top] = Tr;//根节点入栈
	while (tree[i] != '\n') { //输入字符还未读取完
		if (tree[i] != '#') {//读入字符不为空‘#’
			Tr = (BiTree)malloc(sizeof(BiTNode));
			Tr->data.value = tree[i];
			Tr->data.num = n + 1;
			Tr->lchild = Tr->rchild = NULL;
			while (stack[top]->rchild != NULL) top--;//退回至子节点未满的结点上
			if (top <= -1) {
				fclose(fp);
				return NULL;
			}
			
			Tp = stack[top];//栈顶元素赋值给Tp
			stack[++top] = Tr;//当前元素进栈
			if (tree[i - 1] != '#') Tp->lchild = Tr;
			else {
				Tp->rchild = Tr;
			}
			n++;
		}
		else {//读入字符为空‘#’
			while (stack[top]->rchild != NULL) top--;
			Tp = stack[top];
			if (tree[i - 1] != '#')//若前一字符不为空,则将栈顶元素左孩子赋空
				Tp->lchild = NULL;
			else {//前一字符为空,将栈顶元素右孩子赋空值,栈顶元素退栈,栈顶指针左移
				Tp->rchild = NULL;
				top--;
			}
		}
		i++;//下一个字符
	}
	(*T)->data.num = n;	//头结点保存二叉树结点数
	fclose(fp);
	return *T;
}

BiTree FindNode(BiTree T, int e) {//查找节点标记为e的结点,返回结点指针
	int top = 0;
	BiTree stack[100], Tp;
	if (T->lchild == NULL) return NULL;//空树
	stack[top] = T->lchild;
	while (top > -1) {
		Tp = stack[top--];	//核对栈顶元素,栈顶元素退栈
		if (Tp->data.num == e) {//查找到,返回结点指针
			return Tp;
		}
		if (Tp->rchild) stack[++top] = Tp->rchild;//当前节点不匹配,若当前节点右孩子不空,当前节点右孩子入栈
		if (Tp->lchild) stack[++top] = Tp->lchild;//当前节点不匹配,若当前节点左孩子不空,当前节点左孩子入栈
	}
	return NULL;//未查找到,返回NULL
}

TreeList CopyBitree(BiTree T) {//根据二叉树T创建一个相同结构和值的树,返回根节点
	BiTree stack[100], Tp,Tr,Tq;
	int i = 0, top = -1, n = 1;
	char tree[100];
	if (T == NULL) {//空树
		return NULL;
	}
	stack[++top] = T;//根节点进栈
	while (top > -1) {//栈不空
		Tp = stack[top--];//栈顶元素赋值给Tp
		if (Tp) {//Tp不为空
			tree[i++] = Tp->data.value;
			stack[++top] = Tp->rchild;//Tp所指结点右孩子进栈
			stack[++top] = Tp->lchild;//Tp所指结点左孩子进栈
		}
		else {//Tp为空
			tree[i++] = '#';
		}
	}
	tree[i] = '\n';
	i = 1;
	top = -1;

	Tr = (BiTree)malloc(sizeof(BiTNode));//为当前指针分配存储空间
	Tr->data.value = tree[0];	//为当前节点赋值
	Tr->data.num = 1; //为当前节点打标记
	Tr->lchild = Tr->rchild = NULL;

	T = Tr;	//将当前树根结点指针赋给T
	stack[++top] = T;//根节点入栈
	while (tree[i] != '\n') { //输入字符还未读取完
		if (tree[i] != '#') {//读入字符不为空‘#’
			Tr = (BiTree)malloc(sizeof(BiTNode));
			Tr->data.value = tree[i];
			Tr->data.num = n + 1;
			Tr->lchild = Tr->rchild = NULL;
			while (stack[top]->rchild != NULL) top--;//退回至子节点未满的结点上
			if (top <= -1) return NULL;
			Tq = stack[top];//栈顶元素赋值给Tq
			stack[++top] = Tr;//当前元素进栈
			if (tree[i - 1] != '#') Tq->lchild = Tr;
			else {
				Tq->rchild = Tr;
			}
			n++;
		}
		else {//读入字符为空‘#’
			while (stack[top]->rchild != NULL) top--;
			Tq = stack[top];
			if (tree[i - 1] != '#')//若前一字符不为空,则将栈顶元素左孩子赋空
				Tq->lchild = NULL;
			else {//前一字符为空,将栈顶元素右孩子赋空值,栈顶元素退栈,栈顶指针左移
				Tq->rchild = NULL;
				top--;
			}
		}
		i++;//下一个字符
	}
	return T;
}

TreeList TreeTrabverse(TreeList Ts) {//遍历管理链表,返回尾节点指针
	if (Ts == NULL) {
		printf("当前二叉树数目为零\n");
		return NULL;
	}
	TreeList Tq = Ts;
	while (Tq->next) Tq = Tq->next;
	return Tq;
}

TreeList Find(TreeList Ts,int mode, char *treeName, BiTree *T) {//查找指定名称的二叉树,将根节点指针赋值给T,返回管理链表中该二叉树结点指针
	TreeList Tp = Ts;
	if (Ts == NULL) return FALSE;		//二叉树数目为0,返回FALSE
	TreeList Tq = Tp->next;
	if (TreeNum == 1 && mode != 2) return ERROR;		//查找前驱和后继时,管理链表只有一个二叉树,返回ERROR
	switch (mode)
	{
	case 1://查找指定二叉树前驱
		if (strcmp(Ts->name, treeName) == 0) return ERROR;//所查找二叉树是首节点所管理,无前驱
		while (Tq != NULL) {
			if (strcmp(Tq->name, treeName) == 0) return Tp;
			Tp = Tq;
			Tq = Tq->next;
		}
		return ERROR;

	case 2://查找指定二叉树
		while (Tp != NULL) {
			if (strcmp(Tp->name, treeName) == 0) {
				*T = Tp->Root;
				return Tp;
			}
			Tp = Tp->next;
		}
		return ERROR;

	case 3://查找指定二叉树后继
		while (Tq != NULL) {
			if (strcmp(Tp->name, treeName) == 0) return Tq;
			Tp = Tq;
			Tq = Tq->next;
		}
		return ERROR;
	}
}

int main(void){
	BiTree T = NULL, P,T1,T2,Test;			//二叉树根节点指针T
	TreeList Ts = NULL;  		//用于管理二叉树的链表的头指针Ts,前驱指针Tp,遍历指针Tr,后继指针Tt
	TreeList Tp,Tr,Tt;
	int op = 1, flag = 0, mode,i=0,k=0,e = 0,LR;			//操作序号在0-20之间
	char treeName[20],ChildTreeName[20],input[100], c, value;		//二叉树名称用数组treeName保存
	char filename[30];
	while (op) {
		system("cls");
		printf("\n\n");
		printf("      Menu for BiTree On List Structure \n");
		printf("-------------------------------------------------\n");
		printf("     1. InitBiTree       12. RightChild\n");
		printf("     2. DestroyBiTree    13. LeftSibling\n");
		printf("     3. CreateBiTree     14. RightSibling\n");
		printf("     4. ClearBiTree      15. InsertChild\n");
		printf("     5. BiTreeEmpty      16. DeleteChild\n");
		printf("     6. BiTreeDepth      17. PreOrderTraverse\n");
		printf("     7. Root             18. InOrderTraverse\n"); 
		printf("     8. Value            19. PostOrderTraverse\n");
		printf("     9. Assign           20. LevelOrderTraverse\n");
		printf("     10.Parent           21. SaveBiTree\n");
		printf("     11.LeftChild        22. ReadBiTree\n");
		printf("     0. Exit\n");
		printf("-------------------------------------------------\n");
		printf("    请选择你的操作[0~22]: ");
		scanf("%d", &op); getchar();
		switch (op) {
		case 1:
			//InitBiTree
			printf("请输入需要进行初始化操作的二叉树名称: ");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) {
				if (InitBiTree(&T) == OK) {
					TreeNum++;
					printf("二叉树初始化成功! 当前二叉树数目为:%d\n", TreeNum);
					if (1 == TreeNum) { //管理链表添加第一个二叉树信息
						Ts = (TreeList)malloc(sizeof(Tree));
						if (Ts == NULL) exit(OVERFLOW);
						Ts->Root = T;
						Ts->next = NULL;
						strcpy(Ts->name, treeName);
					}
					else
					{ //在管理链表表尾添加新二叉树信息
						Tt = TreeTrabverse(Ts);
						Tr = (TreeList)malloc(sizeof(Tree));
						if (Tr == NULL) exit(OVERFLOW);
						Tr->Root = T;
						strcpy(Tr->name, treeName);
						Tt->next = Tr;
						Tr->next = NULL;
					}
				}
				else printf("二叉树初始化失败!\n");
			}
			else printf("初始化失败,该名称已存在!\n");
			system("pause");
			break;


		case 2:
			//DestroyBiTree
			printf("请输入需要进行销毁操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			Tt = Find(Ts, 1, treeName, &T);//Tt赋值为所查找到的二叉树在管理链表中的前驱结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (DestroyBiTree(T) == OK) {
					if (strcmp(Ts->name, treeName) == 0) {//销毁的二叉树是管理链表首节点所管理
						Tt = Ts;
						Ts = Ts->next;
						free(Tt);
						Tt = NULL;
					}
					else {//销毁的二叉树不是首节点所管理
						Tr = Tt->next;
						Tt->next = Tt->next->next;
						free(Tr);
						Tr = NULL;
					}
					TreeNum--;
					printf("二叉树销毁成功!\n");
					T = NULL;
				}
				else printf("二叉树销毁失败!\n");
			}
			system("pause");
			break;

		case 3:
			//CreateBiTree 
			printf("请输入需要进行创建的二叉树名称: ");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) {
				printf("二叉树未初始化,是否进行初始化? 0.否 1.是 \n");
				scanf("%d", &flag); getchar();
				if (flag == 1){
					if (InitBiTree(&T) == OK) {
						TreeNum++;
						printf("二叉树初始化成功! 当前二叉树数目为:%d\n", TreeNum);
						if (1 == TreeNum) { //管理链表添加第一个二叉树信息
							Ts = (TreeList)malloc(sizeof(Tree));
							if (Ts == NULL) exit(OVERFLOW);
							Ts->Root = T;
							Ts->next = NULL;
							strcpy(Ts->name, treeName);
						}
						else
						{ //在管理链表表尾添加新二叉树信息
							Tt = TreeTrabverse(Ts);
							Tr = (TreeList)malloc(sizeof(Tree));
							if (Tr == NULL) exit(OVERFLOW);
							Tr->Root = T;
							strcpy(Tr->name, treeName);
							Tt->next = Tr;
							Tr->next = NULL;
						}
					}
					else {
						printf("二叉树初始化失败!\n");
						system("pause");
						break;
					}
				}
				else {
					printf("二叉树创建失败,二叉树未初始化\n");
					system("pause");
					break;
				}
			}
			printf("请按先序顺序,不含空格的,依次输入各结点元素(char),'#'代表该结点为空:\n");
			i = 0; k = 0;
			while ((c = getchar()) != '\n') {//逐个读取输入字符
				input[i] = c;
				i++;
			}
			input[i] = '\n';

			if (strstr(input, "#####") != NULL) printf("输入数据不合法!\n");
			else {
				if (BiTreeEmpty(T) == FALSE) {
					printf("二叉树已定义,是否重新定义? 0.否 1.是\n");
					scanf("%d", &flag); getchar();
					if (flag == 1) ClearBiTree(T);
					else{
						printf("二叉树已定义,创建失败\n");
						system("pause");
						break;
					}
				}
			
				i = CreateBiTree(T, input);//用i接收函数返回值

				if (OK == i || INFEASTABLE == i) {
					printf("二叉树创建成功! 当前二叉树数目为:%d\n", TreeNum);
					if (INFEASTABLE == i) printf("所构造二叉树为空二叉树!\n");
				}
				else printf("二叉树创建失败!\n");
					
			}
			system("pause");
			break;

		case 4:
			//ClearBiTree
			printf("请输入需要进行清空操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (ClearBiTree(T) == OK) printf("清空二叉树成功!\n");
				else printf("清空二叉树失败!\n");
			}
			system("pause");
			break;

		case 5:
			//BiTreeEmpty
			printf("请输入需要进行判断是否为空操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (TRUE == BiTreeEmpty(T)) printf("二叉树为空!\n");
				else printf("二叉树不为空!\n");
			}
			system("pause");
			break;

		case 6:
			//BiTreeDepth
			printf("请输入需要进行求深度操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else{
				if (T->lchild == NULL) printf("二叉树为空,深度为0\n");
				else{
					i = BiTreeDepth(T->lchild);
					printf("二叉树深度为: [%d]\n", i);
				}
			}
			system("pause");
			break;

		case 7:
			//Root
			printf("请输入需要进行求树根操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else{
				if (Root(T) == ERROR) printf("当前二叉树为空树,无树根\n");
				else printf("当前二叉树根节点标记和值为:%d :%c\n ", T->lchild->data.num,T->lchild->data.value);
			}
			system("pause");
			break;

		case 8:
			//Value
			printf("请输入需要进行获得节点e的值操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空树!\n");
				else{
					printf("请输入需进行获得值的节点: ");
					scanf("%d", &e); getchar();
					if (e<1 || e>T->data.num) printf("节点参数不合法!\n");
					else{
						c = Value(T, e);
						if (c == ERROR) printf("未找到该节点!\n");
						else printf("该节点是二叉树结点,结点值为:%c\n", c);
					}
				}
			}
			system("pause");
			break;

		case 9:
			//Assign
			printf("请输入需要进行给节点e赋值value操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空树!\n");
				else {
					printf("请输入需进行赋值的节点: ");
					scanf("%d", &e); getchar();
					printf("请输入赋值value: ");
					scanf("%c", &value); getchar();
					if (e<1 || e>T->data.num) printf("节点参数不合法!\n");
					else {
						i = Assign(T, e, value);
						if (i == OK) printf("赋值成功!\n");
						else printf("赋值失败!\n");
					}
				}
			}
			system("pause");
			break;

		case 10:
			//Parent
			printf("请输入需要进行获得双亲结点操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空树!\n");
				else {
					printf("请输入需进行获得双亲结点的节点: ");
					scanf("%d", &e); getchar();
					if (e<1 || e>T->data.num) printf("节点参数不合法!\n");
					else {
						T = Parent(T, e);
						if (T == NULL)printf("查找失败!\n");
						else{
							printf("查找成功!双亲结点标记为:%d\n", T->data.num);
						}
					}
				}
			}
			system("pause");
			break;

		case 11:
			//LeftChild
			printf("请输入需要进行获得左孩子结点操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空树!\n");
				else {
					printf("请输入需进行获得左孩子结点的节点: ");
					scanf("%d", &e); getchar();
					if (e<1 || e>T->data.num) printf("节点参数不合法!\n");
					else {
						T = LeftChild(T, e);
						if(T == NULL) printf("查找失败!\n");
						else printf("查找成功!左孩子结点标记为:%d\n", T->data.num);
					}
				}
			}
			system("pause");
			break;

		case 12:
			//RightChild
			printf("请输入需要进行获得右孩子结点操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空树!\n");
				else {
					printf("请输入需进行获得右孩子结点的节点: ");
					scanf("%d", &e); getchar();
					if (e<1 || e>T->data.num) printf("节点参数不合法!\n");
					else {
						T = RightChild(T, e);
						if (T == NULL) printf("查找失败!\n");
						else printf("查找成功!右孩子结点标记为:%d\n", T->data.num);
					}
				}
			}
			system("pause");
			break;

		case 13:
			//LeftSibling
			printf("请输入需要进行获得左兄弟结点操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空树!\n");
				else{
					printf("请输入需进行获得左兄弟结点的节点: ");
					scanf("%d", &e); getchar();
					if (e<1 || e>T->data.num) printf("节点参数不合法!\n");
					else {
						T = LeftSibling(T, e);
						if (T == NULL) printf("查找失败!\n");
						else printf("查找成功!左兄弟结点标记为:%d\n", T->data.num);
					}
				}
			}
			system("pause");
			break;

		case 14:
			//RightSibling
			printf("请输入需要进行获得右兄弟结点操作的二叉树名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空树!\n");
				else {
					printf("请输入需进行获得右兄弟结点的节点: ");
					scanf("%d", &e); getchar();
					if (e<1 || e>T->data.num) printf("节点参数不合法!\n");
					else {
						T = RightSibling(T, e);
						if (T == NULL) printf("查找失败!\n");
						else printf("查找成功!右兄弟结点标记为:%d\n", T->data.num);
					}
				}
			}
			system("pause");
			break;

		case 15:
			//InsertChild
			printf("请输入需要进行插入子树操作的被插入二叉树的名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				printf("请输入需要进行插入子树操作子树的名称:\n");
				scanf("%s", ChildTreeName); getchar();
				Tr = Find(Ts, 2, ChildTreeName, &T1);//T1赋值为所查找到的子树根结点指针
				if(!Tr) printf("二叉树不存在!\n");
				else{
					if (BiTreeEmpty(T1) == TRUE) printf("作为子树的二叉树为空树!\n");
					else {
						if (T1->lchild->rchild != NULL) printf("子树右子树不空!\n");
						else {
							printf("请输入插入节点的标记:");
							scanf("%d", &e); getchar();
							P = FindNode(T, e);
							if (P == NULL) printf("未查找到该结点!\n");
							else {
								printf("请输入插入位置:0.插入子树作为结点左子树 1.插入子树作为结点右子树 \n");
								scanf("%d", &LR); getchar();
								if (LR < 0 || LR>1) printf("插入位置参数不合法!\n");
								else{
									T2 = CopyBitree(T1->lchild);
									if (InsertChild(T, P, LR, T2) == OK) printf("插入成功!\n");
									else printf("插入失败!\n");
								}
							}
						}
					}
				}
			}
			system("pause");
			break;

		case 16:
			//DeleteChild
			printf("请输入需要进行删除子树操作的二叉树的名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				printf("请输入删除其子树的指定节点的标记:");
				scanf("%d", &e); getchar();
				P = FindNode(T, e);
				if (P == NULL) printf("未查找到该结点!\n");
				else {
					printf("请输入删除位置:0.删除结点的左子树 1.删除结点的右子树 \n");
					scanf("%d", &LR); getchar();
					if (LR < 0 || LR>1) printf("删除位置参数不合法!\n");
					else {
						switch (LR) {
						case 0:
							if (P->lchild != NULL) {
								if (DeleteChild(T, P, LR) != NULL) printf("删除成功!\n");
								else printf("删除失败!\n");
								break;
							}
							else{
								printf("结点左子树为空!\n");
								break;
							}

						case 1:
							if (P->rchild != NULL) {
								if (DeleteChild(T, P, LR) != NULL) printf("删除成功!\n");
								else printf("删除失败!\n");
								break;
							}
							else {
								printf("结点右子树为空!\n");
								break;
							}
						}
						

					}
				}
			}
			system("pause");
			break;

		case 17:
			//PreOrderTraverse
			printf("请输入需要进行前序遍历(基于栈的非递归实现)操作的二叉树的名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空\n");
				else {
					printf("二叉树标记和结点值为:\n");
					PreOrderTraverse(T->lchild);
					printf("\n");
				}
			}
			system("pause");
			break;

		case 18:
			//InOrderTraverse
			printf("请输入需要进行中序遍历(递归实现)操作的二叉树的名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空\n");
				else {
					printf("二叉树标记和结点值为:\n");
					InOrderTraverse(T->lchild);
					printf("\n");
				}
			}
			system("pause");
			break;

		case 19:
			//PostOrderTraverse
			printf("请输入需要进行后序遍历(递归实现)操作的二叉树的名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空\n");
				else {
					printf("二叉树标记和结点值为:\n");
					PostOrderTraverse(T->lchild);
					printf("\n");
				}
			}
			system("pause");
			break;

		case 20:
			//LevelOrderTraverse
			printf("请输入需要进行按层遍历(非递归实现)操作的二叉树的名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空\n");
				else {
					printf("二叉树标记和结点值为:\n");
					LevelOrderTraverse(T->lchild);
					printf("\n");
				}
			}
			system("pause");
			break;

		case 21:
			//SaveBiTree
			printf("请输入需要进行(无空格前序序列,‘#’代表结点为空)保存操作的二叉树的名称:\n");
			scanf("%s", treeName); getchar();
			Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
			if (!Tr) printf("二叉树不存在!\n");
			else {
				printf("请输入保存文件名,以‘.txt’结尾: ");
				scanf("%s", filename); getchar();
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空\n");
				if (SaveBiTree(T->lchild, filename) != OK) printf("保存失败!\n");
				else printf("保存成功\n");
			}
			system("pause");
			break;

		case 22:
			//ReadBiTree
			printf("请选择加载二叉树方式:1.加载到已存在的二叉树 2.加载到新二叉树\n");
			scanf("%d", &mode); getchar();
			printf("请输入加载文件名,以‘.txt’结尾: ");
			scanf("%s", filename); getchar();
			if (mode == 1) {
				printf("请输入二叉树名称: ");
				scanf("%s", treeName); getchar();
				Tr = Find(Ts, 2, treeName, &T);//Tr赋值为所查找到的二叉树在管理链表中的结点指针
				if (!Tr) printf("二叉树不存在!\n");
				else{
					ClearBiTree(T);
					if (ReadBiTree(&T, filename, mode) != NULL) {
						printf("加载成功\n");
						printf("当前二叉树数目为:%d\n", TreeNum);
					}
					else printf("加载失败\n");
				}
			}
			if (mode == 2) {
				printf("请输入二叉树名称: ");
				scanf("%s", treeName); getchar();
				if (ReadBiTree(&T,filename,mode) != NULL) {
					TreeNum++;
					printf("二叉树加载成功! 当前二叉树数目为:%d\n", TreeNum);
					if (1 == TreeNum) { //管理链表添加第一个二叉树信息
						Ts = (TreeList)malloc(sizeof(Tree));
						if (Ts == NULL) exit(OVERFLOW);
						Ts->Root = T;
						Ts->next = NULL;
						strcpy(Ts->name, treeName);
					}
					else
					{ //在管理链表表尾添加新二叉树信息
						Tt = TreeTrabverse(Ts);
						Tr = (TreeList)malloc(sizeof(Tree));
						if (Tr == NULL) exit(OVERFLOW);
						Tr->Root = T;
						strcpy(Tr->name, treeName);
						Tt->next = Tr;
						Tr->next = NULL;
					}
				}
				else printf("二叉树加载失败!\n");
			}
			system("pause");
			break;

		case 0:
			//exit
			if (!T) break;
			printf("是否需要保存当前二叉树? 1.Yes 2.No\n");
			scanf("%d", &mode); getchar();
			if (mode == 1) {
				printf("请输入保存文件名,以‘.txt’结尾: ");
				scanf("%s", filename); getchar();
				if (BiTreeEmpty(T) == TRUE) printf("二叉树为空\n");
				if (SaveBiTree(T->lchild, filename) != OK) printf("保存失败!\n");
				else printf("保存成功\n");
			}
			break;
		}
	}
	printf("欢迎下次再使用本系统!\n");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值