二叉树
创建树:
ABC$$DE$G$$F$$$

最主要的,结构体的构建
#define OK 1
#define ERROR 0
#define MAX_TREE_SIZE 100//树的初始空间大小
#define STACK_INIT_SIZE 100//栈的初始空间大小
#define STACKINCREMENT 10//增栈
typedef char TElemType;//树中存储的是字符
typedef bool Status;
typedef struct BiTNode{
TElemType data;//数据域
struct BiTNode *lchild ,*rchild;//指针域
}BiTNode,*BiTree;
BiTree T;
typedef BiTree SElemType;//栈里存的是指针
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
用到的栈子函数(详细了解栈点击传送)
Status InitStack(SqStack &S)//初始化栈
{
S.base=(SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status PushStack(SqStack &S,SElemType p)//入栈
{
if(S.top-S.base>=S.stacksize)
{
S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++ = p;
return OK;
}
Status PopStack(SqStack &S,SElemType &p)//出栈
{
if(S.top == S.base) return ERROR;
p=*--S.top;
return OK;
}
Status TopStack(SqStack &S,SElemType &p)//取栈顶元素
{
if(S.top==S.base)
return ERROR;
p=*(S.top-1);
return OK;
}
步入正题
1.创建树
Status createBiTree(BiTree &T)
{
char ch;
cin>>ch;//字符型数据
if(ch=='$')
T=NULL;//如果输入为'$',说明该结点为空
else
{
if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
T->data=ch;//存储
createBiTree(T->lchild);//访问该结点的左结点
createBiTree(T->rchild);//访问该结点的右结点
}
return OK;
}
(输出结点的数据)//这个子函数不是写在其他函数内的,是供其他函数反复调用的 啊啊啊卡了好久
Status Print(TElemType e)
{
printf("%c ",e);//just输出字符型变量e
return OK;
}
2.先序遍历//递归方法
Status preTree(BiTree &T,Status(* visit)(TElemType e))
//第二个参数就是用来调用Print函数的
{
if(T)
{
if(visit(T->data))//输出写在最前面,就是先序遍历
if(preTree(T->lchild,Print))//接着访问左子树(递归)
if(preTree(T->rchild,Print))//最后访问右子树
return OK;
return ERROR;
}
return OK;
}
3.后序遍历//递归方法
Status postTree(BiTree &T,Status(* visit)(TElemType e))
{
if(T)
{
if(postTree(T->lchild,Print))
if(postTree(T->rchild,Print))
if(visit(T->data))//同理,输出放在最后面就是后序遍历
return OK;
return ERROR;
}
return OK;
}
4.中序遍历的递归方法就不写了,就是把输出函数放在两个递归子树中间即可。
这里说一下中序遍历的两种非递归(用栈模拟)算法:
(一)通过不断地取栈顶元素
Status inTree1(BiTree T,Status(* visit)(TElemType e))
{
SqStack S;
InitStack(S);//初始化一个栈S
SElemType p;
PushStack(S,T);//根指针入栈
while(S.top!=S.base)
{
while(TopStack(S,p) && p)
PushStack(S,p->lchild);//向左走到尽头,取最后一个结点的左子树(我们知道是空的,所以下一步出栈)
PopStack(S,p);//空指针出栈
if(S.top!=S.base)//访问结点
{
PopStack(S,p);//出栈
if(!visit(p->data))//输出该结点的数据域(此时该结点已出栈)
return ERROR;
PushStack(S,p->rchild);//访问该结点的右子树(若为空,则进行下一次循环时首先会出栈)
}
}
}//手动模拟一下就懂了
(二)通过不断地入栈出栈
Status inTree2(BiTree T,Status(* visit)(TElemType e))
{
SqStack S;
InitStack(S);
SElemType p;
p=T;
while(p || S.top!=S.base)
{
if(p)
{
PushStack(S,p);//根指针入栈
p=p->lchild;//遍历左子树
}
else
{
PopStack(S,p);//根指针出栈
if(!visit(p->data))//输出根结点
return ERROR;
p=p->rchild;//遍历右子树
}
}
return OK;
}
5.层序遍历
Status cengTree(BiTree &T,Status(* visit)(TElemType e))
{
int i=0,j=0;//i用来访问,j用来存
BiTree p[100];//数指针数组
if(T)
p[j++]=T;
while(i<j)
{
visit(p[i]->data);//每访问一个结点,就把它的左右子树存进数组里
if(p[i]->lchild)
p[j++]=p[i]->lchild;
if(p[i]->rchild)
p[j++]=p[i]->rchild;
i++;
}
}
6.求树的深度
int DeepTree(BiTree T)
{
int LD,RD;//LD指最远左子树深度,RD指最远右子树深度
if(T==NULL)
return 0;
else
{
LD=DeepTree(T->lchild);//递归
RD=DeepTree(T->rchild);
return (LD>=RD?LD:RD)+1;//最后加上根节点那一层
}
}
完整代码如下:
#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
#define OK 1
#define ERROR 0
#define MAX_TREE_SIZE 100
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef char TElemType;
typedef bool Status;
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild ,*rchild;
}BiTNode,*BiTree;
BiTree T;
typedef BiTree SElemType;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
Status InitStack(SqStack &S)
{
S.base=(SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status PushStack(SqStack &S,SElemType p)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++ = p;
return OK;
}
Status PopStack(SqStack &S,SElemType &p)
{
if(S.top == S.base) return ERROR;
p=*--S.top;
return OK;
}
Status TopStack(SqStack &S,SElemType &p)
{
if(S.top==S.base)
return ERROR;
p=*(S.top-1);
return OK;
}
Status createBiTree(BiTree &T)
{
char ch;
cin>>ch;
if(ch=='$')
T=NULL;
else
{
if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
T->data=ch;
createBiTree(T->lchild);
createBiTree(T->rchild);
}
return OK;
}
Status Print(TElemType e)
{
printf("%c ",e);
return OK;
}
Status preTree(BiTree &T,Status(* visit)(TElemType e))
{
if(T)
{
if(visit(T->data))
if(preTree(T->lchild,Print))
if(preTree(T->rchild,Print))
return OK;
return ERROR;
}
return OK;
}
Status inTree1(BiTree &T,Status(* visit)(TElemType e))
{
SqStack S;
InitStack(S);
SElemType p;
PushStack(S,T);
while(S.top!=S.base)
{
while(TopStack(S,p) && p)
PushStack(S,p->lchild);
PopStack(S,p);
if(S.top!=S.base)
{
PopStack(S,p);
if(!visit(p->data))
return ERROR;
PushStack(S,p->rchild);
}
}
}
Status inTree2(BiTree T,Status(* visit)(TElemType e))
{
SqStack S;
InitStack(S);
SElemType p;
p=T;
while(p || S.top!=S.base)
{
if(p)
{
PushStack(S,p);
p=p->lchild;
}
else
{
PopStack(S,p);
if(!visit(p->data))
return ERROR;
p=p->rchild;
}
}
return OK;
}
Status postTree(BiTree &T,Status(* visit)(TElemType e))
{
if(T)
{
if(postTree(T->lchild,Print))
if(postTree(T->rchild,Print))
if(visit(T->data))
return OK;
return ERROR;
}
return OK;
}
Status cengTree(BiTree &T,Status(* visit)(TElemType e))
{
int i=0,j=0;
BiTree p[100];
if(T)
p[j++]=T;
while(i<j)
{
visit(p[i]->data);
if(p[i]->lchild)
p[j++]=p[i]->lchild;
if(p[i]->rchild)
p[j++]=p[i]->rchild;
i++;
}
}
int DeepTree(BiTree T)
{
int LD,RD;
if(T==NULL)
return 0;
else
{
LD=DeepTree(T->lchild);
RD=DeepTree(T->rchild);
return (LD>=RD?LD:RD)+1;
}
}
int main()
{
cout<<"***********************************************"<<endl;
cout<<"************ 1.创建二叉树 *****************"<<endl;
cout<<"************ 2.先序遍历二叉树 *****************"<<endl;
cout<<"************ 3.中序遍历二叉树1 *****************"<<endl;
cout<<"************ 4.中序遍历二叉树2 *****************"<<endl;
cout<<"************ 5.后序遍历二叉树 *****************"<<endl;
cout<<"************ 6.层序遍历二叉树 *****************"<<endl;
cout<<"************ 7.求二叉树的深度 *****************"<<endl;
cout<<"************ 8.退出 ****************"<<endl;
cout<<"***********************************************"<<endl;
int n;
do
{
cout<<"请输入选择:" ;
cin>>n;
switch(n)
{
case 1:
cout<<"输入:";
createBiTree(T);
cout<<"创建成功"<<endl;
break;
case 2:
cout<<"前序遍历:";
preTree(T,Print);
cout<<endl;
break;
case 3:
cout<<"中序遍历1:";
inTree1(T,Print);
cout<<endl;
break;
case 4:
cout<<"中序遍历2:";
inTree2(T,Print);
cout<<endl;
break;
case 5:
cout<<"后序遍历:";
postTree(T,Print);
cout<<endl;
break;
case 6:
cout<<"层序遍历:";
cengTree(T,Print);
cout<<endl;
break;
case 7:
cout<<"该二叉树的深度是:";
cout<<DeepTree(T)<<endl;
break;
default :
cout<<"输入指令不存在"<<endl;
break;
}
}while(n!=8);
cout<<"程序已退出,欢迎下次使用"<<endl;
return 0;
}
I can do it.
1754

被折叠的 条评论
为什么被折叠?



