码农小汪-剑指Offer之7 - 重建二叉树(根据前序遍历中序遍历求二叉树)

本文介绍了一种根据二叉树的前序遍历和中序遍历结果重建二叉树的方法。通过递归地确定根节点及其左右子树,逐步构建完整的二叉树结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
根左右(前序) 中序左根右 肯定有相同的地方值得考虑。通过递归的思路解决问题

解题思路:

1.先求出根节点(前序序列第一个元素)。
2.将根节点带入到中序遍历序列中求出左右子树的中序遍历序列。
3.通过左右子树的中序序列元素集合带入前序遍历序列可以求出左右子树的前序序列。
4.左右子树的前序序列第一个元素分别是根节点的左右儿子
5.求出了左右子树的4种序列可以递归上述步骤

分析

已知一棵二叉树的先序遍历序列和中序遍历序列分别是abdgcefh、dgbaechf,求二叉树及后序遍历序列.
分析:先序遍历序列的第一个字符为根结点.对于中序遍历,根结点在中序遍历序列的中间,左边部分是根结点的左子树的中序遍历序列,右边部分是根结点的右子树的中序遍历序列.
先序:abdgcefh –> a bdg cefh
中序:dgbaechf –> dgb a echf
得出结论:a是树根,a有左子树和右子树,左子树有bdg结点,右子树有cefh结点.
先序:bdg –> b dg
中序:dgb –> dg b
得出结论:b是左子树的根结点,b无右子树,有左子树.
先序:dg –> d g
中序:dg –> d g
得出结论:d是b的左子树的根结点,d无左子树,有右子树.
先序:cefh –> c e fh
中序:echf –> e c hf
得出结论:c是右子树的根结点,c有左子树(只有e结点),有右子树(有fh结点).
先序:fh –> f h
中序:hf –> h f
得出结论:f是c的左子树的根结点,f有左子树(只有h结点),无右子树.
还原二叉树为:
a
b c
d e f
g h

package JianzhiOffer;

/**
 * 输入某二叉树的前序遍历和中序遍历的结果, 请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 例如
 * 输入前序遍历序列{1,2,4,7,3,5,6,8} 和中序遍历序列{4,7,2,1,5,3,8,6}, 则重建二叉树并返回。
 * 
 * @author JetWang
 *
 */
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

public class Sloution7 {
    public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
        if (pre.length != in.length || pre.length == 0 || in.length == 0)
            return null;
        int Root = pre[0];// 先序遍历的头结点
        // 2 在中序遍历中找到头结点
        int i;
        for (i = 0; i < in.length; i++) {
            if (Root == in[i]) {
                break;
            }
        }
        int[] pre_Left = new int[i];
        int[] in_Left = new int[i];
        int[] pre_Right = new int[in.length - i - 1], in_Right = new int[in.length
                - i - 1];// 总的长度少了1个,就是Root;
        for (int j = 0; j < in.length; j++) {
            if (j < i) {
                in_Left[j] = in[j];
                pre_Left[j] = pre[j + 1];
                /**
                 * 这里的意思是,我的中序有多少个左子树, 我们的前序那面就有多少个左子树
                 */

            } else if (j > i) {
                in_Right[j - i - 1] = in[j];
                pre_Right[j - i - 1] = pre[j];
                // 后面的位置没有动静
            }
        }
        TreeNode rooTreeNode = new TreeNode(Root);
        rooTreeNode.left = reConstructBinaryTree(pre_Left, in_Left);
        rooTreeNode.right = reConstructBinaryTree(pre_Right, in_Right);
        return rooTreeNode;
        /**
         * 就这样递归的解决了,问题哦!
         */

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值