二叉树的遍历

1.先序遍历

遍历过程:
1.访问根结点。
2.先序遍历其左子树。
3.先序遍历其右子树。
代码实现(递归):

void PreOrderTraversal(BinTree BT)
{
    if(BT){
        printf("%d", BT->Data);           //访问根结点
        PreOrderTraversal( BT->Left);     //先序遍历左子树
        PreOrderTraversal( BT->Right);    //先序遍历右子树
        }
}

代码实现(非递归-堆栈):

void PreOrderTraversal(BinTree BT)
{
    BinTree T = BT;
    Stack S = CreatStack( MaxSize);       //创建并初始化堆栈S
    while( T || !IsEmpty(S))
    {
            while(T)                     
        {
            printf("%5d", T->Data);      //(访问)打印结点
            T = T->Left;
            Push(S,T);

        }
        if(!IsEmpty(S))
        {
            T = Pop(S);                  //结点弹出堆栈
            T = T->Right;               //转向右子树
        }
    }
}

图解:
这里写图片描述

输出结果为:ABDFECGHI

2.中序遍历
遍历过程:
1.中序遍历其左子树
2.访问根结点
3.中序遍历右子树

代码实现(递归):

void InOrderTraversal(BinTree BT)
{
    if(BT){
        InOrderTraversal( BT->Left);     //中序遍历左子树
        printf("%d", BT->Data);          //访问根结点
        InOrderTraversal( BT->Right);    //中序遍历右子树
        }
}

代码实现(非递归-堆栈):

void InOrderTraversal(BinTree BT)
{
    BinTree T = BT;
    Stack S = CreatStack( MaxSize);       //创建并初始化堆栈S
    while( T || !IsEmpty(S))
    {
            while(T)                      //一直向左并将沿途结点压入堆栈
        {
            Push(S,T);
            T = T->Left;
        }
        if(!IsEmpty(S))
        {
            T = Pop(S);                  //结点弹出堆栈
            printf("%5d", T->Data);      //(访问)打印结点
            T = T->Right;               //转向右子树
        }
    }
}

图解:

这里写图片描述

输出结果为:DBEFAGHCI

3.后序遍历

遍历过程:
1.后序遍历其左子树
2.后序遍历其右子树
3.访问根节点

代码实现(递归):

void PostOrderTraversal(BinTree BT)
{
    if(BT){
            PostOrderTraversal( BT->Left);     //后序遍历左子树    
            PostOrderTraversal( BT->Right);    //后序遍历右子树    
            printf("%d", BT->Data);             //访问根节点 
        }

}

图解

这里写图片描述

输出结果为:DEFBHGICA

共同点

这里写图片描述
先序、中序和后序便利过程:便利过程中结点的路线一样,只是访问各结点的时机不同。
图中在从入口到出口的曲线上各用赞中符号分别标记出了先序、中序和后序访问结点的时刻。

4.层次遍历
二叉树遍历的核心问题:二维结构的线性化.
1.从结点访问其左、右儿子结点。
2.访问左儿子后,需要用一个存储结构暂时保存不访问的结点。

队列实现:遍历从根结点开始,首先将根节点入队,然后开始执行循环:结点出队、访问该结点、其左右儿子入队。

基本过程 :先根结点入队,然后:
1.从队列中取出一个元素
2.访问钙元素所指结点
3.若钙元素所指结点的左右孩子结点非空,将其左右孩子的指针顺序入队

代码实现

void LevelOrderTraversal( BinTree BT)
{
    Queue Q;
    BinTree T;
    if(!BT) return;                   //若是空树则直接返回
    Q = CreatQueue( MaxSize);         //创建并初始化队列Q
    AddQ( Q, BT);
    while( !IsEmptyQ(Q))
    {
        T = DeleteQ( Q);
        printf("%d\n", T->Data);      //访问取出队列的结点
        if( T->Left) AddQ( Q, T->Left);
        if( T->right) AddQ( Q, T->right);
    }
}

应用

1.输出二叉树中的叶子结点

在二叉树的遍历算法中增加检测结点的“左右儿子树是否都为空”

void PreOrderTraversal(BinTree BT)
{
    if(BT){
        if(!BT->Left && BT->Right)        
            printf("%d", BT->Data);              
        PreOrderTraversal( BT->Left);     //先序遍历左子树
        PreOrderTraversal( BT->Right);    //先序遍历右子树
        }
}

2.求二叉树的高度

分析:Height = Max(LeftHeigth,RightHeigth)+1

void PostOrderTraversal(BinTree BT)
{
    int HL, HR, MaxH;
    if(BT){
            HL = PostOrderTraversal( BT->Left);     //后序遍历左子树   
            HR = PostOrderTraversal( BT->Right);    //后序遍历右子树
            MaxH = (HL > HR )? HL : HR;             //取左右儿子最大深度
            return MaxH+1   
        }

}

3.二元运算表达式树及其遍历

表达式树:
这里写图片描述

先序遍历得到前缀表达式:++a*bc*+*defg
中序遍历得到中缀表达式:a+b*c+d*e+f*g
后序遍历得到后缀表达式:abc*+de*f+g*+

注:中缀表达式会收到运算符优先级的影响

可以用加括号的方法。输出左子树时先加一个左括号,输出右子树时再输出右括号。

4.由两种遍历序列确定二叉树

必须要有中序遍历才行!

这里写图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值