根据中序遍历和后序遍历树构造二叉树

本文介绍如何根据给定的中序和后序遍历序列重建二叉树,并提供详细的解题思路及完整的Java代码实现。

一、题目描述

根据中序遍历和后序遍历树构造二叉树

注意事项:可以假设树中不存在相同数值的节点

样例
给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2]

返回如下的树:

   2
 /   \
1     3

二、解题思路

思路和用前序遍历和后序遍历树构造二叉树类似
1、首先根据后序遍历序列的最后一个数字创建根结点(后序遍历序列的最后一个数字就是根结点)
2、然后在中序遍历序列中找到根结点所在的位置,这样就能确定左、右子树结点的数量,这样也就分别找到了左、右子树的中序遍历序列和后序遍历序列。
3、然后用递归的方法去构建左、右子树,直到叶子结点。

三、代码实现

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */


public class Solution {
    /**
     *@param inorder : A list of integers that inorder traversal of a tree
     *@param postorder : A list of integers that postorder traversal of a tree
     *@return : Root of a tree
     */
    //在中序遍历序列中找到根结点的位置
    private int findPosition(int[] array, int start, int end, int key) {
        for (int i = start; i <= end; i++) {
            if (array[i] == key) {
                return i;
            }
        }
        return -1;
    }
    //重建二叉树,通过递归调用来一步步的重建
    private TreeNode myBuildTree(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd) {
        if (inStart > inEnd) {
            return null;
        }
        //根据后序遍历序列的最后一个数字建立根结点root
        TreeNode root = new TreeNode(postorder[postEnd]);
        //获取根结点的位置position
        int position = findPosition(inorder, inStart, inEnd, postorder[postEnd]);
        //创建左子树
        root.left = myBuildTree(inorder, inStart, position - 1, postorder, postStart, postStart + (position - inStart- 1));
        //创建右子树
        root.right = myBuildTree(inorder, position + 1, inEnd, postorder, postStart + (position - inStart), postEnd - 1);
        return root;    //返回根结点
    }
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        // write your code here
        if (inorder.length != postorder.length) {
            return null;
        }
        return myBuildTree(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
    }

}

四、注意事项

在序列中划分左、右子树时,确定数组下标一定要仔细,否则很容易出现数组越界异常,且得不到正确的二叉树。

### 中序遍历后序遍历构造二叉树的方法 要通过中序遍历后序遍历的结果重建二叉树,可以采用递归方法。以下是详细的说明: #### 思路分析 1. 后序遍历的最后一个节点总是当前子树的根节点[^1]。 2. 利用该根节点,在中序遍历序列中找到其位置,从而划分出左子树右子树的范围[^3]。 3. 对于左子树右子树分别重复上述过程,直至处理完所有的节点。 #### 实现步骤 下面是一个基于 Java 的实现代码示例,用于根据序遍历后序遍历结果构建二叉树: ```java class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class BuildTreeFromInPost { private int postIndex; public TreeNode buildTree(int[] inorder, int[] postorder) { if (inorder == null || postorder == null || inorder.length != postorder.length) { return null; } this.postIndex = postorder.length - 1; // 初始化为后序遍历的最后一个索引 return helper(inorder, postorder, 0, inorder.length - 1); } private TreeNode helper(int[] inorder, int[] postorder, int inStart, int inEnd) { if (inStart > inEnd) { return null; } // 当前子树的根节点是从后序遍历中的postIndex获取到的 TreeNode root = new TreeNode(postorder[postIndex]); postIndex--; // 更新后序遍历指针 // 在中序遍历中查找根节点的位置 int inIndex = findIndex(inorder, inStart, inEnd, root.val); // 构建右子树(注意这里是先构建右子树) root.right = helper(inorder, postorder, inIndex + 1, inEnd); // 构建左子树 root.left = helper(inorder, postorder, inStart, inIndex - 1); return root; } private int findIndex(int[] inorder, int start, int end, int value) { for (int i = start; i <= end; i++) { if (inorder[i] == value) { return i; } } return -1; } } ``` #### 关键点解释 1. **后序遍历的特点**:后序遍历的顺序是“左 -> 右 -> 根”,因此每次递归时可以从 `postorder` 数组的末尾取出当前子树的根节点[^4]。 2. **中序遍历的作用**:利用中序遍历能够快速定位左右子树的边界,进而缩小问题规模[^3]。 3. **递归终止条件**:当 `inStart > inEnd` 时表示当前区间为空,返回 `null` 即可[^1]。 --- ###
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值