美文网首页
算法-二叉树的遍历实现

算法-二叉树的遍历实现

作者: jkwen | 来源:发表于2021-05-15 10:33 被阅读0次

    简述

    二叉树的遍历分 DFS【深度优先遍历】 和 BFS【广度优先遍历】 两类,其中 DFS 又分为前序遍历,中序遍历和后续遍历。算法实现上 DFS 用递归容易实现,BFS 用队列容易实现,但用递归的方式也可以用栈来实现,用队列的地方也可以用递归来实现,所以总的来看可以有 8 个实现结果。

    思路

    前序遍历

    xx 遍历中的 xx 都是相对根节点来说的,如果根节点先遍历输出,那就是前序,如果根节点介于左节点和右节点那就是中序。
    假设给定一个以链表形式的二叉树的根节点,

    1. 首先会先输出当前这个节点 A,
    2. 接着看 A 节点的左节点,存在的话就可以重复步骤 1 了。
    3. 再接着看 A 节点的右节点,存在的话也去重复步骤 1 的操作。

    这样一来步骤 2 和 3 就是递归操作了。

    中序遍历

    思路同前序遍历,不同点在于输出的顺序要调整,

    1. 首先如果 A 节点的左节点存在,就继续重复步骤 1 。
    2. A 节点的左节点不存在或者遍历过了,输出当前 A 节点。
    3. 如果 A 节点的右节点存在,重复步骤 1 。

    相比前序遍历,就是对应的父节点输出顺序的不同。

    后序遍历

    依照前面两个的思路,后续遍历就好推导了,

    1. 首先如果 A 节点的左节点存在,就继续重复步骤 1 。
    2. 如果 A 节点的右节点存在,重复步骤 1 。
    3. 如果 A 节点的左右节点都不存在或者遍历过了,输出当前 A 节点。

    以上就是 DFS 的递归实现思路,下面来梳理下 DFS 的栈实现思路。

    前序遍历

    用栈实现的思路我是通过试探的,目前仅做了些实例验证,可能会有问题,找时间通过平台验证下正确性。
    考虑到前序遍历的输出要求,又结合栈的先进后出的特点,我的思路是,

    1. 先将根节点入栈。
    2. 再循环栈,判断栈不为空时,就出栈顶元素输出。
    3. 接着将该元素的右节点和左节点分别入栈。
    4. 重复步骤 2 。

    我这个其实没按方法栈的思路,如果按方法栈的思路,其实就是对递归实现的翻译。就是说方法调用方法其实就是入栈操作,那么翻译上面的前序遍历递归实现应该是,

    1. 先入栈根节点,接着不停的入栈左节点,直到没有。这就对应着递归里的第 2 步。
    2. 接着做出栈操作,之后需要把出栈元素的右节点作为根节点入栈。然后就是重复步骤 1。这就对应着递归里的第 3 步。
    3. 就前两步不断执行,直到栈空就结束了。

    中序遍历

    我的思路是,

    1. 还是先入栈根节点,然后不停入栈左节点,这步其实和前序类似。
    2. 然后循环判断栈是否为空,不为空,则出栈打印。
    3. 然后如果出栈元素的右节点不为空就入栈,同时以该节点为根,不停入栈其左节点,直到左节点为空。
    4. 循环重复步骤 2,3 。直到栈空。

    这整理发现和前序遍历按着递归实现的翻译思路很像。

    后序遍历

    我的思路是,

    1. 还是先入栈根节点,然后不停入栈左节点,这步和上面也是一样的。
    2. 然后循环判断栈是否为空,不为空的话,先获取栈顶元素,注意此时不出栈。
    3. 然后判断如果右节点为空则输出栈顶元素值,并移除栈顶元素。
    4. 如果右节点不为空则将右节点入栈,注意这里会把栈顶节点的右节点引用关联断开,然后将右节点的左节点一直入栈,知道左节点为空。
    5. 循环步骤 2,3,4,直到栈空。

    这种实现最终会破坏树的结构,所以后来我又考虑,判断右节点是否已经输出,如输出了,即使右节点不为空也不会入栈了,而是继续下个节点操作。

    层序遍历

    层序遍历需要用到队列的思想,因为是一层一层的输出,所以,

    1. 将根节点入队。
    2. 循环判断队列是否为空,不为空则出队列打印,然后分别将左节点和右节点入栈。
    3. 重复步骤 2,直到队列为空结束。

    层序遍历的递归实现方式,我理解的就是把循环体进行函数封装然后递归,

    1. 还是利用队列,先将根节点入队。
    2. 然后判断队列是否为空,遍历队列出队打印,并将左节点和右节点入队。
    3. 重复步骤 2 实现递归,直到遍历完整棵树。

    代码

    考虑到代码需要调试运行,我将写好的代码放在了 github 上,方便整理记录。

    github地址:二叉树遍历实现

    相关文章

      网友评论

          本文标题:算法-二叉树的遍历实现

          本文链接:https://www.haomeiwen.com/subject/azwydltx.html