算法——二叉树的遍历方法

11 篇文章 10 订阅
5 篇文章 1 订阅

前言

二叉树的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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值