二叉树的遍历(递归)先中后序

本文介绍了二叉树的链式存储结构,并详细讲解了二叉树的先序、中序和后序递归遍历方法,通过具体的访问顺序和递归思想解释了遍历过程,提供了相应的算法描述。

在《二叉树的结构特点和性质》一片文章中我们简单了解了树和二叉树的定义,以及二叉树的一些性质和结构特点,没有看的或者对二叉树不熟悉的同学可以先去看一下,文章链接https://blog.youkuaiyun.com/qq_34322188/article/details/82346068,必须先了解二叉树的结构,才会让你更容易的去学习怎么去遍历一棵二叉树。

存储结构

      二叉树的存储结构有两种:顺序存储结构和链式存储结构,由于顺序存储结构存在的很大的局限性,所以我们以链式存储结构讲解为主。

如左面的图所示,data域用于存储对应的数据元素,lchildrchild分别表示左指针和右指针域,分别用于存储左孩子和右孩子结点的位置,这种存储结构又称为二叉链表存储结构。下面给出结点类型的定义:

typedef struct BTNode
{
     char data;
     struct BTNode *lchild;
     struct BTNode *rchild;
}BTNode;

                                  

                                                                          图 1 

下面对图1中的二叉树来理解一下先中后序的递归遍历,当你理解了之后就会发现遍历so easy

先序遍历(递归)

访问顺序:(1)访问根结点

                  (2)先序遍历左子树

                  (3)先序遍历右子树

描述:由上面访问顺序的三个步骤你也能看出递归的思想,第一步先访问根结点;第二步先序遍历左子树,这时你可以把左子树单独当做一棵树再执行上述的三个步骤,访问根结点,如果还有左子树,再访问左子树的根结点......这就是递归的体现;第三步先序遍历右子树,跟第二步思想一样先是访问根节点,有左子树先访问左子树,然后右子树,直到树被遍历完。

       图1先序遍历的结果为:ABDECFG

       对应的算法描述如下:

void preorder(BTNode *t)
{
    if(t!=NULL)
    {
        
        Visit(t);   // 假设Visit()已被定义,包含了对结点t的一系列操作。
        
        preorder(t->lchild);  // 先序遍历左子树
    
        preorder(t->lchild);  // 先序遍历右子树
    
    }
}

中序遍历(递归)

访问顺序:(1)中序遍历左子树

                  (2)访问根结点

                  (3)中序遍历右子树

描述:由上面访问顺序的三个步骤你也能看出递归的思想,第一步中序遍历左子树,这时你可以把左子树单独当做一棵树再执行上述的三个步骤,如果还有左子树,先访问左子树,如果还有左子树......直到左子树的左孩子为空,第二步先访问根结点;第三步中序遍历右子树,跟第一步思想一样有左子树先访问左子树,然后根结点,最后右子树,直到树被遍历完。

       图1中序遍历的结果为:DBEACFG

       对应的算法描述如下:

void inorder(BTNode *t)
{
    if(t!=NULL)
    {
        
        inorder(t->lchild);  // 中序遍历左子树
        
        Visit(t);   // 假设Visit()已被定义,包含了对结点t的一系列操作。
    
        inorder(t->lchild);  // 中序遍历右子树
    
    }
}

后序遍历(递归)

访问顺序:(1)后序遍历左子树

                  (2)后序遍历右子树

                  (3)访问根结点

描述:由上面访问顺序的三个步骤你也能看出递归的思想,第一步后序遍历左子树,这时你可以把左子树单独当做一棵树再执行上述的三个步骤,如果还有左子树,先访问左子树,如果还有左子树......直到左子树的左孩子或者右孩子为空,第二步后序遍历右子树,跟第一步思想一样有左子树先访问左子树,然后右子树,最后根结点;第三步先访问根结点,直到树被遍历完。

        图1后序遍历的结果为:DEBFGCA

        对应的算法描述如下:

void postorder(BTNode *t)
{
    if(t!=NULL)
    {
        
        postorder(t->lchild);  // 后序遍历左子树
    
        postorder(t->lchild);  // 后序遍历右子树

        Visit(t);   // 假设Visit()已被定义,包含了对结点t的一系列操作。
    
    }
}

总结

       针对上述的先中后序的三种递归遍历算法,我们观看一下代码实现:都是递归调用方法,唯一不同的是函数Visit()在遍历方法中的位置不同。

        先序遍历:函数Visit()在递归调用最前执行,这样就能先访问根结点。

        中序遍历:函数Visit()在递归调用中间执行,这样就能先访问左子树的结点然后访问根结点。

        后序遍历:函数Visit()在递归调用最后执行,这样就能后访问根结点。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值