/*遍历有伪代码*/
/*二叉树的遍历*/
#include<bits/stdc++.h>
using namespace stdl;
#define OK 1
#define ERROR -1
#define OVERFLOW -2
typedef int BElemType;
typedef int Status;
typedef struct BTNode
{
BElemType data;
struct BTNode* lchild;
struct BTNode* rchild;
struct BTNode* node;
bool isfirst;
} BTNode,*BiTree;
//求叶子数
int GetNumberofleaf(BiTree T)
{
//如果是空树就返回0
if(T==NULL)
return 0;
//只要没有左孩子和右孩子就加一
if(!T->lchild&&!T->rchild)
return 1;
//有左孩子和右孩子就一直向下走
else
return GetNumberofleaf(T->lchild)+GetNumberofleaf(T->rchild);
}
//求节点数
int GetNumberofNode(BiTree T)
{
//如果是一个空树就返回0
if(T==NULL)
return 0;
//不是空树就返回左孩子的结点数加右孩子的结点数
else
return 1+GetNumberofNode(T->lchild)+GetNumberofNode(T->rchild);
}
//求深度
int GetDepth(BiTree T)
{
if(!T)
return 0;
else
{
int d1=1+GetDepth(T->lchild),d2=1+GetDepth(T->rchild);
return d1>d2?d1:d2;
}
}
//销毁
Status DestroyBiTree(BiTree &T)
{
if(!T)
return OK;
else
{
DestroyBiTree(T->lchild);
DestroyBiTree(T->rchild);
free(B);
B=NULL;
}
}
//递归初始化
Status CreatBiTree(BiTree &T)
{
TElemType e;
cin>>e;
if(!e)
return OK;
else
{
T=(BiTree)malloc(sizeof(BiTNode));
if(!T)exit(OVERFLOW);
T->data=e;
CreatBiTree(T->lchild);
CreatBiTree(T->rchild);
return OK;
}
}
//递归方法实现的周游路径完全相同//输出不同序的递归是因为输出的结点不对
Status PreOrderTraversal(BiTree T)
{
if(!T)
return OK;
else
{
cout<<T->data;
PreOrderTraversal(T->lchild);
PreOrderTraversal(T->rchild);
return OK;
}
}
//非递归方法实现中序遍历
//主体流程是先把根入栈,一直访问左子树,出栈,有右子树,进入新一轮循环
//关键是一直左走,退到二叉树中间的元素,转到右边,重新进入循环
Status InOrderTraversal(BiTree T)
{
while(T||!isEmpty(S))//非空执行找左子树找右子树操作,栈不为空执行出栈并找右子树操作
{
while(T)
{
Push(S,T);
T=T->lchild;
}
if(!isEmpty(S))
{
T=Pop(S);
cout<<T->data<<endl;
T=T->rchild;
}
}
}
//先序遍历的非递归
//因为前中后遍历的顺序完全一样,只是输出的顺序不一样
Status PreOrderTraversal(BiTree T)
{
stack S;
while(T||!isEmpty(S))
{
while(T)
{
Push(T);
cout<<T->data<<endl;
T=T->lchild;
}
if(!isEmpty(S))
{
T=Pop(S);
T=T->rchild;
}
}
}
//后序遍历的非递归实现/*两个栈*/
//要保证左子树和右子树都被访问完了才能访问
//输出的要求:根节点在栈底,右结点在栈中,左结点在栈顶。
//循环
//每次结点直接入栈1,循环条件是栈1不为空,从栈1出栈之后进入栈2
Status PostOrderTraversal(Bitree T)
{
stack S1,S2;
BiTree p,q;
Push(S1,T);
while(!isEmpty(S1))
{
p=Pop(S1);//栈1里面出来一个
Push(S2,p);//从栈1出栈进入栈2
if(q->lchild)//向左走
{
Push(S1,q->lchild);
}
if(q->rchild)//向右走
{
Push(S1,q->rchild);
}
}
while(!isEmpty(S2))//现在栈2顺序就是后序
{
q=Pop(S2);
cout<<q->data<<endl;
}
}
//后序遍历非递归/*找到第二次遇到的时候输出*/
//在结构体中需要加一个flag判断是第几次遇到的结点
Status PostOrderTraversal(BiTree T)
{
stack S;
BiTree p=T;
BiTree t;
while(p||!isEmpty(S))
{
while(p)//一直往左走
{
BiTree c=(BiTree)malloc(sizeof(BTNode));
c->node=p;
c->isfirst=true;//进栈是第一次遇到
Push(S,c);
p=p->lchild;
}
if(!isEmpty(S))//走到左边头上了
{
t=Pop(S);//开始出栈
if(t->isfirst)//出栈的时候是第二次遇到
{
t->isfirst=false;
Push(S,t);//入栈
p=t->rchild;//向右边走
}
else
{
cout<<t->data<<endl;//又一次遇到是第三次遇到了直接输出。
p=NULL;
}
}
}
}
//层序遍历
//二叉树遍历要解决的问题:访问左子树之后你要找到根节点,继续找到右子树
//队列的应用
Status LevelOrderTraversal(BiTree T)
{
Queue Q;
BiTree f;
if(!T)return OK;//如果是空树就返回OK
CreateQueue(Q);
EnQueue(Q,T);//先让跟入队
while(!isEmpty(Q))//只要队里面还有元素
{
f=DeQueue(Q);//让最前面的出来并输出
cout<<f->data<<endl;
if(f->lchild)EnQueue(Q,f->lchild);//让左右儿子入队
if(f->rchild)EnQueue(Q,f->rchild);
}
return OK;
}
二叉树的基础操作
最新推荐文章于 2024-09-28 20:44:11 发布