前言
二叉树的5种遍历方法,以及二叉树的结点计算方法的实现(C++)。
二叉树的中序遍历的非递归算法,需要用到栈的相关操作;
二叉树的层序遍历算法,需要用到循环队列的相关操作。
1.栈的相关操作
栈的存储结构及其初始化
#define StackMAXSIZE 100
typedef BiTNode* SElemType; //栈中保存的数据是二叉树结点的指针
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
void InitStack(SqStack &S)
{
S.base=new SElemType[StackMAXSIZE];
if(!S.base)
{
return;
}
S.top=S.base;
S.stacksize=StackMAXSIZE;
}
入栈和出栈
void Push(SqStack &S,SElemType p)
{
if(S.top-S.base==S.stacksize)
{
return;
}
*S.top=p; //新指针入栈
S.top++;
}
void Pop(SqStack &S,SElemType &q)
{
if(S.top==S.base)
{
return;
}
S.top--;
q=*S.top;
}
栈空的判断
bool StackEmpty(SqStack S)
{
if(S.top==S.base)
return true;
else
return false;
}
2.队列的相关操作
队列的存储结构及其初始化
#define QueueMAXSIZE 100
typedef BiTNode* QElemType;
typedef struct
{
QElemType *base;
int frontQ;
int rearQ;
}Queue;
void InitQueue(Queue &Q)
{
Q.base=new QElemType[QueueMAXSIZE];
if(!Q.base)
{
return;
}
Q.frontQ=Q.rearQ=0;
}
入队和出队
void pushQ(Queue &Q,QElemType T)
{
if((Q.rearQ+1)%QueueMAXSIZE==Q.frontQ)
{
return;
}
Q.base[Q.rearQ]=T;
Q.rearQ=(Q.rearQ+1)%QueueMAXSIZE;
}
QElemType popQ(Queue &Q)
{
QElemType e=Q.base[Q.frontQ];
Q.frontQ=(Q.frontQ+1)%QueueMAXSIZE;
return e;
}
队空的判断
bool QueueEmpty(Queue Q)
{
if(Q.frontQ==Q.rearQ)
return true;
else
return false;
}
3.二叉树的相关操作
二叉树的存储结构
typedef char TElemType;
typedef struct BiTNode{
TElemType data; //结点数据域
struct BiTNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;
二叉树的相关操作
//先序遍历的顺序建立二叉链表
void CreateBiTree(BiTree &T)
{//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin>>ch;
if(ch=='#') T=NULL; //递归结束,建空树
else //递归创建二叉树
{
T=new BiTNode; //生成根结点
T->data=ch; //根结点数据域置为ch
CreateBiTree(T->lchild); //递归创建左子树(先)
CreateBiTree(T->rchild); //递归创建右子树(后)
} //else
}
//中序遍历二叉树T的递归算法
void InOrderTraverse1(BiTree T)
{
if(T)
{//若二叉树非空
InOrderTraverse1(T->lchild); //中序遍历左子树
cout<<T->data; //访问根结点
InOrderTraverse1(T->rchild); //中序遍历右子树
}
}
//先序遍历二叉树T的递归算法
void StartTraverse(BiTree T)
{
if(T)
{//若二叉树非空
cout<<T->data; //访问根结点
StartTraverse(T->lchild); //中序遍历左子树
StartTraverse(T->rchild); //中序遍历右子树
}
}
//后序遍历二叉树T的递归算法
void EndTraverse(BiTree T)
{
if(T)
{//若二叉树非空
EndTraverse(T->lchild); //中序遍历左子树
EndTraverse(T->rchild); //中序遍历右子树
cout<<T->data; //访问根结点
}
}
//中序遍历的非递归算法
void InOrderTraverse2(BiTree T)
{
SqStack S;
InitStack(S);
BiTree p=T;
BiTNode *q=new BiTNode;
while(p||!StackEmpty(S))
{
if(p) //p非空
{
Push(S,p); //根指针进栈
p=p->lchild; //根指针进栈,遍历左子树
}
else //p为空
{
Pop(S,q); //退栈
cout<<q->data; //访问根结点
p=q->rchild; //遍历右子树
}
} //while
}
//层序遍历二叉树
void LevelTraverse(BiTree T)
{
//参考https://blog.csdn.net/m0_37925202/article/details/80796010
//初始化队列
Queue Q;
InitQueue(Q);
//层序遍历二叉树
if(T!=NULL)
{
pushQ(Q,T);//根结点入队
}
while(QueueEmpty(Q)==false)
{//当队列不为空
cout<<Q.base[Q.frontQ]->data;
if(Q.base[Q.frontQ]->lchild!=NULL)
{//队头的根结点,如果有左孩子,将左孩子入队
pushQ(Q,Q.base[Q.frontQ]->lchild);
}
if(Q.base[Q.frontQ]->rchild!=NULL)
{//队头的根结点,如果有右孩子,将右孩子入队
pushQ(Q,Q.base[Q.frontQ]->rchild);
}
popQ(Q);//将已遍历过的根结点出队
}
}
//统计二叉树中结点的个数
int NodeCount(BiTree T)
{//统计二叉树T中结点的个数
if(T==NULL) //如果是空树,则结点个数为0,递归结束
return 0;
else //否则结点个数为左子树的结点个数+右子树的结点个数+1
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
//计算二叉树的深度
int Depth(BiTree T)
{//计算二叉树T的深度
if(T==NULL)
return 0;//如果是空树,深度为0,递归结束
else
{
int m=Depth(T->lchild);//递归计算左子树的深度记为m
int n=Depth(T->rchild);//递归计算右子树的深度记为n
if(m>n)
return (m+1);
else
return (n+1);
}
}
测试代码
int main()
{
BiTree T;
cout<<"请按先序次序输入二叉树的值(一个字符),子树为空则输入“#”号:"<<endl;
CreateBiTree(T);
cout<<"先序遍历:"<<endl;
StartTraverse(T);
cout<<"\n后序遍历:"<<endl;
EndTraverse(T);
cout<<"\n中序遍历(递归):"<<endl;
InOrderTraverse1(T);
cout<<"\n中序遍历(非递归):"<<endl;
InOrderTraverse2(T);
cout<<"\n层序遍历:"<<endl;
LevelTraverse(T);
cout<<"\n二叉树中结点个数为:"<<NodeCount(T)<<endl;
cout<<"二叉树的深度为:"<<Depth(T)<<endl;
return 0;
}