二叉树前序、中序、后序遍历相互求法

        二叉树是数据结构中的重要知识点,最近准备笔试的时候总是会有以下问题:如果知道二叉树的两种遍历,如何求第三种遍历。本文将说明如何根据二叉树的两种遍历构建二叉树,进而求出第三种遍历方式,最后给出由前序、中序构建二叉树的代码实现。

我们知道,二叉树的遍历有三种,分别是前序遍历、中序遍历和后序遍历,我们来看看这三种遍历的特性:

  • 前序遍历(根-->左-->右)

        1.访问根节点 

        2.前序遍历左子树 

        3.前序遍历右子树

 

  • 中序遍历(左-->根-->右)

        1.中序遍历左子树 

        2.访问根节点 

        3.中序遍历右子树

 

  • 后序遍历(左-->右-->根)

        1.后序遍历左子树

        2.后序遍历右子树

        3.访问根节点

 

一、已知前序、中序遍历,求后序遍历

已知

前序遍历: ABGDECFH

中序遍历: GBEDAFCH

构建二叉树步骤:

  1. 根据前序遍历的特点,我们知道根结点root为A
  2. 观察中序遍历GBEDAFCH。其中root节点A的左侧GBED必然是root的左子树,右侧FCH必然是root的右子树。同时,这个也分别是左子树和右子树的中序遍历的序列;
  3. 在前序遍历遍历完根节点后,接着执行前序遍历左子树,注意,是前序遍历,什么意思?就是把左子树当成一棵独立的树,执行前序遍历,同样先访问左子树的根,第2步我们已经知道左子树是BGDE(前序遍历序列)了,由此可以得到,左子树的根是B,那么在这一步得到左子树的根是B
  4. 从第2步得到的中序遍历的节点序列中,找到B,发现B左边只有一个G,说明B的左子树只有一个叶子节点,B的右边呢?我们可以得到B的右子树有ED,再看前序遍历的序列,发现D在前,也就是说,D是先前序遍历访问的,则得到ED的左子树,只有一个叶子节点。到这里,我们可以得到这棵树的根结点和左子树的结构了,如下图:

                                                                             

5. 接着看右子树,在第2步的时候已经知道右子树是FCH这三个节点,那么先看前序遍历的序列,先出现的是C那么C就是右子树的根结点,看右子树的中序遍历为FCH所以FH就分别是它的左子树和右子树,因此,右子树的结构就出来了,如下图:

                                                                              

6. 把左子树和右子树连接起来,可以得到整棵树的结构:

                                                                      

7. 最后由二叉树的结构可以得到后序遍历序列为:GEDBFHCA

 

二、已知中序、后序遍历,求前序遍历

已知

中序遍历: GBEDAFCH

后序遍历:GEDBFHCA

步骤和上面的类似,还是得先找出根结点,由后序遍历的特点,根结点root在最后,所以根结点为A再由中序遍历可以知道左子树和右子树分别为GBEDFCH;再按照上面的步骤递归分别求出左右子树即可得解。

 

三、已知前序、后序遍历,求中序遍历

        已知前序、中序或者中序、后序都可以唯一确定一棵二叉树,但是已知前序、后序是无法唯一确定一棵二叉树的,解不唯一。

 

四、已知前序、中序,重构二叉树

       输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。(剑指offer原题)

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.Arrays;

public class Solution {
    public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
        if (pre.length == 0 || in.length == 0) {
            return null;
        }
        TreeNode node = new TreeNode(pre[0]);
        for (int i = 0; i < in.length; i++) {
            if (pre[0] == in[i]) {
                node.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));
                node.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i + 1, pre.length), Arrays.copyOfRange(in, i + 1, in.length));
            }
        }
        return node;
    }
}

 

五、二叉树的前中序遍历

public void theFirstOrderTraversal(TreeNode node) {  //前序遍历
        if(node==null) //如果结点为空则返回
            return;
        printNode(node);
        theFirstOrderTraversal(node.getLeft());
        theFirstOrderTraversal(node.getRight());
    }

    public void theInOrderTraversal(TreeNode node) {  //中序遍历
        if(node==null) //如果结点为空则返回
            return;
        theInOrderTraversal(node.getLeft());
        printNode(node);
        theInOrderTraversal(node.getRight());
    }

    public void theLastOrderTraversal(TreeNode node) {  //后序遍历
        if(node==null) //如果结点为空则返回
            return;
        theLastOrderTraversal(node.getLeft());
        theLastOrderTraversal(node.getRight());
        printNode(node);
    }

 

  • 53
    点赞
  • 262
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值