#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#ifndef MACRO_//宏
#define MACRO_
#define OK 1
#define FALSE 0
#define TURE 1
#define ERROR 0
#define OVERFLOW -2
#define INFEASIBLE -1
typedef int Status;
typedef int BOOL;
#endif
#define ClearTree DestoryBiTree
typedef int TrElemType;//树元素类型
typedef struct BiTNode
{
TrElemType Data;
struct BiTNode *Lchild, *Rchild;//左右孩子指针
}BiTNode, *BiTree;
#ifndef STElem_Type_//栈元素类型
#define STElem_Type_
/*typedef struct ST_elem_type//定义栈元素类型,为 树指针类型和BOOL类型(创建BOOL类型是为了非递归后序遍历)
{
BiTree ptr;
BOOL bool_type;
}ST_elem_type;
typedef ST_elem_type STElemType; //栈元素类型
*/
typedef BiTree STElemType;
#endif
#include"stack.h"
#ifndef QElem_Type_//队列元素类型
#define QElem_Type_
typedef BiTree QElemType;
#endif
#include"queue.h"
void InitBiTree(BiTree *T);
//构造空二叉树
Status CreateBiTree(BiTree *T);
//按先序次序输入二叉树结点中的值,空格表示空树
//成功返回OK
Status PreOrderTraverse(BiTree T);
//先序遍历二叉树T的递归算法
Status PreOrderTraverse_General(BiTree T);
//二叉树的非递归先序遍历
Status InOrderTraverse(BiTree T);
//中序遍历二叉树T的递归算法
Status InOrderTraverse_General(BiTree T);
//二叉树的非递归中序遍历
Status PostOrderTraverse(BiTree T);
//后序遍历二叉树T的递归算法
/*
Status PostOrderTraverse_General_one(BiTree T)
//二叉树的非递归后续遍历-----------方法1(需要栈元素类型为结构体)
*/
Status PostOrderTraverse_General_two(BiTree T);
//二叉树的非递归后续遍历-----------方法二(需要栈元素类型为树结点指针)
Status LevelOrdefTraverse(BiTree T);
//二叉树的层序遍历
int Count_NodeNum(BiTree T);
//计算结点数
int Count_Leaf(BiTree T);
//计算叶子结点数
BOOL IsEmpty(BiTree T);
//判断树是否为空
int Count_Deep(BiTree T);
//计算树的深度
TrElemType root(BiTree T);
//返回树的根,如果为空树返回-1
void DestoryBiTree(BiTree *T);/*Destory和Clear操作是相同的*/
//销毁二叉树
TrElemType value(BiTree T, BiTree cur_e);
//树T存在,cur_e是T中某个结点
//返回cur_e的值,如果结点为空或树为空,返回-1
Status Assign(BiTree T, BiTree cur_e, TrElemType *value);
//树T存在,cur_e是T中某个结点
//将cur_e的值赋值为value,成功返回OK,如果结点为空或树为空,返回INFEASEBLE
BiTree Parent(BiTree T, BiTree e);
//二叉树T存在,e是T中某个结点
//若e是T的非根结点,则返回他的双亲,否则返回空
BiTree LeftChild(BiTree T, BiTree e);
//二叉树存在,e是T中某个结点
//返回e的左孩子,若e无左孩子,则返回空
BiTree RightChild(BiTree T, BiTree e);
//二叉树存在,e是T中某个结点
//返回e的右孩子,若e无右孩子,则返回空
BiTree LeftSibling(BiTree T, BiTree e);
//二叉树存在,e是T中某个结点
//返回e的左兄弟,若额是T的左孩子或无做兄弟,则返回空
BiTree RightSibling(BiTree T, BiTree e);
//二叉树存在,e是T中某个结点
//返回e的右兄弟,若e是T的右孩子或无右兄弟,则返回空
Status InsertChild(BiTree T, BiTree p, int LR, BiTree c);
//二叉树T存在,p指向T中某个结点,LR为0或1(0指左,1指右),非空二叉树c与T不相交且右子树为空
//根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点的原有左子树或右子树则成为c的右子树
//c有右子树或者p为空返回ERROR,成功返回OK
Status DeleteChild(BiTree T, BiTree p, int LR);
//二叉树T存在,p指向T中某个结点,LR为0或1
//根据LR为0或1,删除T中所指p所指结点的左或右子树
//如果p为空返回ERROR,成功返回OK
/*Input:
ABD EH CF IJ G |带上空格
The NodeNum is 10
The leaf is 4
The Deep is 5
*/
/*Input:
ABD CE FG |带上空格
The NodeNum is 7
The leaf is 3
The Deep is 4
*/
int main()
{
BiTree T,e,test,TestTree;
printf("Please Enter : ");
if (CreateBiTree(&T) == OK)
printf("Creat OK \n");
printf("\nThe preorder traversal: ");
PreOrderTraverse(T);
printf("\nThe inorder traversal: ");
InOrderTraverse(T);
printf("\nThe postorder traversal: ");
PostOrderTraverse(T);
printf("\nThe levelorder traversal: ");
LevelOrdefTraverse(T);
printf("\nThe Preorder traversal of General : ");
PreOrderTraverse_General(T);
printf("\nThe inorder traversal of General : ");
InOrderTraverse_General(T);
printf("\nThe Preorder traversal of General : ");
//PostOrderTraverse_General(T);
PostOrderTraverse_General_two(T);
printf("\n/*************test***********/\n");
TestTree = T->Rchild->Lchild;
if (test=Parent(T, TestTree))//父节点测试
printf("\nParent is %c ", test->Data);
else printf("\nis NULL");
if (test = LeftChild(T, TestTree))//左孩子测试
printf("\nLeft is %c ", test->Data);
else printf("\n no left child");
if (test = RightChild(T, TestTree))//右孩子测试
printf("\nLeft is %c ", test->Data);
else printf("\n no right child");
if (test = LeftSibling(T, TestTree))//左兄弟测试
printf("\nLbro is %c", test->Data);
else printf("\n no left bro");
if (test = RightSibling(T, TestTree))//右兄弟测试
printf("\nRbro is %c", test->Data);
else printf("\n no right bro");
printf("\n/*************test***********/\n");
Count_NodeNum(T);
printf("\nThe NodeNum is %d ", Count_NodeNum(T));
printf("\nThe leaf is %d ", Count_Leaf(T));
printf("\nThe Deep is %d ", Count_Deep(T));
IsEmpty(T) ? printf("\nIsEmpty") : printf("\nNoEmpty");
printf("\n/********************test**Insert**Delete*********************/");
printf("\nPlease Enter : ");//新建树e
fflush(stdin);
if (CreateBiTree(&e) == OK)
printf("Creat OK \n");
if (InsertChild(T, T->Rchild, 1, e) == OK)
{
printf("\n--Ins--\n");
Count_NodeNum(T);
printf("\nThe NodeNum is %d ", Count_NodeNum(T));
printf("\nThe leaf is %d ", Count_Leaf(T));
printf("\nThe Deep is %d ", Count_Deep(T));
IsEmpty(T) ? printf("\nIsEmpty") : printf("\nNoEmpty");
printf("\nThe levelorder traversal: ");
LevelOrdefTraverse(T);
}//if
if (DeleteChild(T, T->Rchild, 1) == OK)
{
printf("\n--Del--\n");
Count_NodeNum(T);
printf("\nThe NodeNum is %d ", Count_NodeNum(T));
printf("\nThe leaf is %d ", Count_Leaf(T));
printf("\nThe Deep is %d ", Count_Deep(T));
IsEmpty(T) ? printf("\nIsEmpty") : printf("\nNoEmpty");
printf("\nThe levelorder traversal: ");
LevelOrdefTraverse(T);
}
printf("\n/********************test**Insert**Delete*********************/");
DestoryBiTree(&T);//Destory和Clear效果相同,T和结点都会被释放,被赋值为NULL
printf("\nThe NodeNum is %d ", Count_NodeNum(T));
printf("\nThe leaf is %d ", Count_Leaf(T));
printf("\nThe Deep is %d ", Count_Deep(T));
IsEmpty(T) ? printf("\nIsEmpty") : printf("\nNoEmpty");
system("pause");
}
void InitBiTree(BiTree *T)
//构造空二叉树
{
T = NULL;
}//InitBiTree
Status CreateBiTree(BiTree *T)
//按先序次序输入二叉树结点中的值,空格表示空树
//成功返回OK
{
char ch = getchar();
if (ch == ' ')
*T = NULL;
else
{
(*T) = (BiTree)malloc(sizeof(BiTNode));
if (!(*T))exit(OVERFLOW);
(*T)->Data = ch;
CreateBiTree(&(*T)->Lchild);//构造左子树
CreateBiTree(&(*T)->Rchild);//构造右子树
}//else
return OK;
}//CreateBiTree
void DestoryBiTree(BiTree *T)
//销毁二叉树
{
if (*T)
{
if ((*T)->Lchild)
DestoryBiTree(&(*T)->Lchild);
if ((*T)->Rchild)
DestoryBiTree(&(*T)->Rchild);
free(*T);
(*T) = NULL;
}//if
}//DestoryBiTree
Status PreOrderTraverse(BiTree T)
//采用二叉链表存储结构
//先序遍历二叉树T的递归算法
{
BiTree P = T;
if (P)
{
printf("%c", P->Data);
PreOrderTraverse(P->Lchild);
PreOrderTraverse(P->Rchild);
}//if
return OK;
}//PreOrderTraverse
Status PreOrderTraverse_General(BiTree T)
//二叉树的非递归先序遍历
{
SLinkStack S;
Init_Stack(&S);
STElemType q, p;//栈中元素是结构体
p = T;//p从头到尾只被当成指针,没使用过其BOOL值
while (StackEmpty(S) != TURE || p)
{
if (p)
{
printf("%c", p->Data);
push(S, p);
p = p->Lchild;
}//if
else
{
pop(S, &q);
p = q->Rchild;
}//else
}//while
DestoryStack(&S);
return OK;
}//PreOrderTraverse_General
Status InOrderTraverse(BiTree T)
//采用二叉链表存储结构
//中序遍历二叉树T的递归算法
{
BiTree P = T;
if (P)
{
InOrderTraverse(P->Lchild);
printf("%c", P->Data);
InOrderTraverse(P->Rchild);
}//if
return OK;
}//InOrderTraverse
Status InOrderTraverse_General(BiTree T)
//二叉树的非递归中序遍历
{
SLinkStack S;
Init_Stack(&S);
STElemType q, p;//栈中元素是结构体
p = T; //p从头到尾只被当成指针,没使用过其BOOL值(如果将栈元素类型当成结构体)
while (StackEmpty(S) != TURE || p)
{
if (p)
{
push(S, p);
p = p->Lchild;
}//if
else
{
pop(S, &q);
p = q;
printf("%c", p->Data);
p = p->Rchild;
}//else
}//while
DestoryStack(&S);
return OK;
}//InOrderTraverse_General
Status PostOrderTraverse(BiTree T)
//采用二叉链表存储结构
//后序遍历二叉树T的递归算法
{
BiTree P = T;
if (P)
{
PostOrderTraverse(P->Lchild);
PostOrderTraverse(P->Rchild);
printf("%c", P->Data);
}//if
return OK;
}//PostOrderTraverse
/*Status PostOrderTraverse_General_one(BiTree T)
//二叉树的非递归后续遍历-----------方法1(需要栈元素类型为结构体)
{
SLinkStack S;
Init_Stack(&S);
STElemType p, q;
p.ptr = T;//p从头到尾只被当成指针,没使用过其BOOL值
while (StackEmpty(S)!=TURE||p.ptr)
{
if (p.ptr)
{
p.bool_type = FALSE;//做标志,没有被访问过
push(S, p);
p.ptr = p.ptr->Lchild;//访问左孩子
}//if
else
{
GetTop(S, &q);//取栈顶元素
if (q.bool_type == FALSE)//如果栈顶元素BOOL值为FASLE,说明栈顶元素还未被访问过->(当前为左孩子回溯),接下来要访问他的右孩子
{
p.ptr = q.ptr->Rchild;//访问该结点的右孩子
S->next->data.bool_type = TURE;//修改当前BOOL类型,已经被访问
}//if
else//否则BOOL值为TURE,说明已经被访问过->当前为右孩子回溯
{
pop(S, &q);
printf("%c", q.ptr->Data);
}//else
}//else
}//while
DestoryStack(&S);
return OK;
}//PostOrderTraverse_General
*/
Status PostOrderTraverse_General_two(BiTree T)
//二叉树的非递归后续遍历-----------方法二(需要栈元素类型为树结点指针)
{
SLinkStack S;
Init_Stack(&S);
STElemType p, q, r;
p = T;
while (StackEmpty(S) != TURE || p)
{
if (p)
{
push(S, p);
push(S, p);
p = p->Lchild;
}//if
else
{
pop(S, &q);
if (StackEmpty(S) == TURE)
{
printf("%c", q->Data);
continue;
}//if
else
GetTop(S, &r);//记录栈顶元素
if (r == q)//如果栈顶元素等于刚弹出的栈外元素,说明该元素是第一次弹出
p = q->Rchild;
else
printf("%c", q->Data);
}//else
}//while
return OK;
}//PostOrderTraverse_General_two
Status LevelOrdefTraverse(BiTree T)
//二叉树的层序遍历
{
LinkQueue Q;
InitQueue(&Q);//初始化队列
QElemType e;//队列元素类型为BiTree
Enqueue(&Q, T);
while (QueueEmpty(Q) != TURE)
{
Dequeue(&Q, &e);
if (e)
{
printf("%c", e->Data);
if (e->Lchild)
Enqueue(&Q, e->Lchild);
if (e->Rchild)
Enqueue(&Q, e->Rchild);
}//if
}//while
DestoryQueue(&Q);
return OK;
}//LevelOrdefTraverse
int Count_NodeNum(BiTree T)
//计算结点数
{
if (T)
return Count_NodeNum(T->Lchild) + Count_NodeNum(T->Rchild) + 1;//结点数为左子树结点数+右子树结点数+1
return 0;
}//Count_NodeNum
int Count_Leaf(BiTree T)
//计算叶子结点数
{
if (!T)
return 0;
else if (!T->Lchild&&!T->Rchild)
return 1;
else
return Count_Leaf(T->Lchild) + Count_Leaf(T->Rchild);//叶子结点数为左子树中叶子节点数+右子树中叶子结点数
}//Count_Leaf
int Count_Deep(BiTree T)
//计算树的深度
{
if (T)
return (Count_Deep(T->Lchild) > Count_Deep(T->Rchild) ? Count_Deep(T->Lchild) : Count_Deep(T->Rchild)) + 1; //深度为max(左子树深度,右子树深度)+1
return 0;
}//Count_Deep
BOOL IsEmpty(BiTree T)
//判断树是否为空
{
return !T ? TURE : FALSE;
}//IsEmpty
TrElemType root(BiTree T)
//返回树的根,如果为空树返回-1
{
if (IsEmpty(T) == TURE)
return -1;
return T->Data;
}//root
TrElemType value(BiTree T, BiTree cur_e)
//树T存在,cur_e是T中某个结点
//返回cur_e的值,如果结点为空或树为空,返回-1
{
if (T&&cur_e)
return cur_e->Data;
else return -1;
}//value
Status Assign(BiTree T, BiTree cur_e, TrElemType *value)
//树T存在,cur_e是T中某个结点
//将cur_e的值赋值为value,成功返回OK,如果结点为空或树为空,返回INFEASEBLE
{
if (T&&cur_e)
{
(*value) = cur_e->Data;
return OK;
}//if
else return INFEASIBLE;
}//Assign
BiTree Parent(BiTree T,BiTree e)
//二叉树T存在,e是T中某个结点
//若e是T的非根结点,则返回他的双亲,否则返回空
{
if (NULL == e || e == T)//如果e为根结点或者e为NULL
return NULL;
LinkQueue Q;
QElemType Qelem=NULL;
InitQueue(&Q);//建立队列
Enqueue(&Q, T);//头结点入队
do
{
Dequeue(&Q, &Qelem);
if (Qelem->Lchild)//左孩子不为空,入队
Enqueue(&Q, Qelem->Lchild);
if (Qelem->Rchild)//右孩子不会空,入队
Enqueue(&Q, Qelem->Rchild);
}//do
while ((QueueEmpty(Q) != TURE) && (Qelem->Rchild != e) && (Qelem->Lchild != e)); //队列不空 && 左孩子不为e && 右孩子不为e
if (Qelem->Rchild == e || Qelem->Lchild == e)
return Qelem;
else return NULL;
}//Parent
BiTree LeftChild(BiTree T,BiTree e)
//二叉树存在,e是T中某个结点
//返回e的左孩子,若e无左孩子,则返回空
{
return e ? e->Lchild : NULL;
}//LeftChild
BiTree RightChild(BiTree T,BiTree e)
//二叉树存在,e是T中某个结点
//返回e的右孩子,若e无右孩子,则返回空
{
return e ? e->Rchild : NULL;
}//LeftChild
BiTree LeftSibling(BiTree T,BiTree e)
//二叉树存在,e是T中某个结点
//返回e的左兄弟,若额是T的左孩子或无做兄弟,则返回空
{
BiTree parent = Parent(T,e);
if (parent)
return (e == parent->Lchild) ? NULL : parent->Lchild;//e如果是左孩子,返回NULL,如果不是,返回左孩子(左孩子也可能为NULL)
else return NULL;//parent为空说明e没有父结点或者e为空
}//LeftSibling
BiTree RightSibling(BiTree T, BiTree e)
//二叉树存在,e是T中某个结点
//返回e的右兄弟,若e是T的右孩子或无右兄弟,则返回空
{
BiTree parent = Parent(T, e);
if (parent)
return (e == parent->Rchild )? NULL : parent->Rchild;//e如果是右孩子,返回NULL,如果不是,返回右孩子(右孩子也可能为NULL)
else return NULL;//parent为空说明e没有父结点或者e为空
}//RightSibling
Status InsertChild(BiTree T, BiTree p, int LR, BiTree c)
//二叉树T存在,p指向T中某个结点,LR为0或1(0指左,1指右),非空二叉树c与T不相交且右子树为空
//根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点的原有左子树或右子树则成为c的右子树
//c有右子树或者p为空返回ERROR,成功返回OK
{
if (c->Rchild||!p)
return ERROR;
if (0 == LR)//插入左边
{
c->Rchild = p->Lchild;
p->Lchild = c;
}//if
else
{
c->Rchild = p->Rchild;
p->Rchild = c;
}//else
return OK;
}//InsertChild
Status DeleteChild(BiTree T,BiTree p,int LR)
//二叉树T存在,p指向T中某个结点,LR为0或1
//根据LR为0或1,删除T中所指p所指结点的左或右子树
//如果p为空返回ERROR,成功返回OK
{
if (p)
{
if (0 == LR)
DestoryBiTree(&p->Lchild);
else
DestoryBiTree(&p->Rchild);
return OK;
}//if
return ERROR;
}//DeleteChild