利用二叉树的链式存储结构,设计一组输入数据(假定为一组整数或一组字符),能够对二叉树进行如下操作:
创建一棵空二叉树;
对一棵存在的二叉树进行销毁;
根据输入某种遍历次序输入二叉树中结点的值,依序建立二叉树;
判断某棵二叉树是否为空;.求二叉树的深度;
求二叉树的根结点,若为空二叉树,则返回一特殊值;
二叉树的遍历,即按某种方式访问二叉树中的所有结点,并使每个结点恰好被访问一次;
pubuse.h
#include
#include
#include/*malloc()等*/
#include/*INT_MAX等*/
#include/*EOF(=^Z或F6),NULL*/
#include/*atoi()*/
#include/*eof()*/
#include/*floor(),ceil(),abs()*/
#include/*exit()*/
/*函数结果状态代码*/
#define TRUE 1
#define Nil 0
#define INT
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
/*#defineOVERFLOW-2因为在math.h中已定义OVERFLOW的值为3,故去掉此行*/
typedef int Status;/*Status是函数的类型,其值是函数结果状态代码,如OK等*/
typedef int Boolean;/*Boolean是布尔类型,其值是TRUE或FALSE*/
typedef int TElemType;
BinTreeDef.h
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild;/*вСср╨╒всж╦уК*/
} BiTNode,*BiTree;
“构造空二叉树算法”操作结果:构造一个空二叉树T;
“销毁二叉树算法”初始条件:二叉树T存在;
操作结果:销毁二叉树T;
“创建二叉树算法”初始条件:可以根据先序、中序和后序输入二叉树中结点的值(可为字符型或整型);
操作结果:以选择的某种次序建立二叉树T;
“判二叉树是否为空算法”初始条件:二叉树T存在;
操作结果:若T为空二叉树,则返回TRUE,否则FALSE;
“求二叉树的深度算法”初始条件:二叉树T存在;
操作结果:返回T的深度;
“求二叉树的根算法”初始条件:二叉树T存在;
操作结果:返回T的根;
“先序递归遍历算法”初始条件:二叉树T存在,Visit是对结点操作的应用函数;
操作结果:先序递归遍历T,对每个结点调用函数Visit一次且仅一次;
“中序递归遍历算法”初始条件:二叉树T存在,Visit是对结点操作的应用函数;
操作结果:中序递归遍历T,对每个结点调用函数Visit一次且仅一次;
“后序递归遍历算法”初始条件:二叉树T存在,Visit是对结点操作的应用函数;
操作结果:后序递归遍历T,对每个结点调用函数Visit一次且仅一次;
BinTreeAlgo.h
/*BinTreeAlgo.h二叉树的二叉链表存储(存储结构由BinTreeDef.h定义)的基本操作*/
Status InitBiTree(BiTree &T)
{
/*操作结果:构造空二叉树T*/
T=NULL;
return OK;
}
void DestroyBiTree(BiTree &T)
{
/*初始条件:二叉树T存在。操作结果:销毁二叉树T*/
if(T)/*非空树*/
{
if(T->lchild)/*有左孩子*/
DestroyBiTree(T->lchild);/*销毁左孩子子树*/
if(T->rchild)/*有右孩子*/
DestroyBiTree(T->rchild);/*销毁右孩子子树*/
free(T);/*释放根结点*/
T=NULL;/*空指针赋0*/
}
}
#define ClearBiTreeDestroyBiTree
void CreateBiTree(BiTree &T)
{
/*算法6.4:按先序次序输入二叉树中结点的值(可为字符型或整型,在主程中*/
/*定义),构造二叉链表表示的二叉树T。变量Nil表示空(子)树。有改动*/
TElemType ch;
#ifdef CHAR
scanf("%c",&ch);
getchar();
#endif
#ifdef INT
scanf("%d",&ch);
#endif
if(ch==Nil)/*空*/
T=NULL;
else
{
T=(BiTree)malloc(sizeof(BiTNode));
if(!T)
exit(OVERFLOW);
T->data=ch;/*生成根结点*/
//printf("(%d)\n",ch);
CreateBiTree(T->lchild);/*构造左子树*/
CreateBiTree(T->rchild);/*构造右子树*/
}
}
Status BiTreeEmpty(BiTree T) /*初始条件:二叉树T存在*/
{
/*操作结果:若T为空二叉树,则返回TRUE,否则FALSE*/
if(T) return FALSE;
else return TRUE;
}
int BiTreeDepth(BiTree T)
{
/*初始条件:二叉树T存在。操作结果:返回T的深度*/
int i,j;
if(!T) return 0;
if(T->lchild)
i=BiTreeDepth(T->lchild);
else i=0;
if(T->rchild)
j=BiTreeDepth(T->rchild);
else j=0;
return i>j?i+1:j+1;
}
TElemType Root(BiTree T)
{
/*初始条件:二叉树T存在。操作结果:返回T的根*/
if(BiTreeEmpty(T))return Nil;
else return T->data;
}
TElemType Value(BiTree p)
{
/*初始条件:二叉树T存在,p指向T中某个结点*//*操作结果:返回p所指结点的值*/
return p->data;
}
void Assign(BiTree p,TElemType value)
{
/*给p所指结点赋值为value*/p->data=value;
}
void PreOrderTraverse(BiTree T,Status(*visit)(TElemType))
{
/*初始条件:二叉树T存在,Visit是对结点操作的应用函数。算法6.1,有改动*//*操作结果:先序递归遍历T,对每个结点调用函数Visit一次且仅一次*/
if(T)/*T不空*/
{
visit(T->data);/*先访问根结点*/
PreOrderTraverse(T->lchild,visit);/*再先序遍历左子树*/
PreOrderTraverse(T->rchild,visit);/*最后先序遍历右子树*/
}
}
Status InOrderTraverse(BiTree T,Status(*visit)(TElemType))
{
/*初始条件:二叉树T存在,Visit是对结点操作的应用函数*/
/*操作结果:中序递归遍历T,对每个结点调用函数Visit一次且仅一次*/
if(T)
{
InOrderTraverse(T->lchild,visit);/*先中序遍历左子树*/
visit(T->data);/*再访问根结点*/
InOrderTraverse(T->rchild,visit);/*最后中序遍历右子树*/
return OK;
}
}
Status PostOrderTraverse(BiTree T,Status(*visit)(TElemType))
{
/*初始条件:二叉树T存在,Visit是对结点操作的应用函数*
/*操作结果:后序递归遍历T,对每个结点调用函数Visit一次且仅一次*/
if(T)/*T不空*/
{
PostOrderTraverse(T->lchild,visit);/*先后序遍历左子树*/
PostOrderTraverse(T->rchild,visit);/*再后序遍历右子树*/
visit(T->data);/*最后访问根结点*/
return OK;
}
}
BinTreeUse.cpp
#include"pubuse.h"
#include"BinTreeDef.h"
#include"BinTreeAlgo.h"
Status visitT(TElemType e)
{
#ifdef CHAR
printf("%c ",e);
#endif
#ifdef INT
printf("%d ",e);
#endif
return OK;
}
Status visit(TElemType e)
{
#ifdef CHAR
printf("%c ",e);
#endif
#ifdef INT
printf("%d ",e);
#endif
return OK;
}
int main()
{
int i;
BiTree T,p,c;
TElemType e1,e2;
/*1---基本实验算法的验证 */
InitBiTree(T);
printf("构造空二叉树后,树空否?%d(1:是0:否)树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));
e1=Root(T);
if(e1!=Nil)
#ifdef CHAR
printf("二叉树的根为:%c\n",e1);
#endif
#ifdef INT
printf("二叉树的根为:%d\n",e1);
#endif
if(BiTreeEmpty(T))
printf("树空,无根\n");
#ifdef CHAR
printf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n");
#endif
#ifdef INT
printf("请先序输入二叉树(如:12000表示1为根结点,2为左子树的二叉树)\n");
#endif
CreateBiTree(T);
printf("建立二叉树后,树空否?%d(1:是0:否)树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));
e1=Root(T);
if(e1!=Nil)
#ifdef CHAR
printf("二叉树的根为:%c\n",e1);
#endif
#ifdef INT
printf("二叉树的根为:%d\n",e1);
#endif
if(BiTreeEmpty(T))
printf("树空,无根\n");
PreOrderTraverse(T,visit);
printf("中序递归遍历二叉树:");
InOrderTraverse(T,visit);
printf("\n");
printf("后序递归遍历二叉树:");
PostOrderTraverse(T,visit);
printf("\n");
return 0;
}
建树时类似于深度优先搜索,
输入 1(回车,下同)2 0 4 0 0 3 0 0 得到的树:
1
/ \
2 3
/ \ / \
0 4 0 0
/ \
0 0
深度为3,
先序遍历为1 2 4 3
中序遍历为2 4 1 3
后序遍历为4 2 3 1