(难)【07】根据前序,中序遍历重建二叉树

题目

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
input :
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

思路

这道题我不会做,看了题解之后,才发现有迹可循。可以使用递归。
具体思路我会在代码中注释

收获

递归重建二叉树

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    HashMap<Integer,Integer>dict=new HashMap<>();//用于储存中序遍历
    int po[];//因为代码思路通过索引取值,所以需要两个全局变量
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        po = preorder;
        //为什么要存储中序数组?
        //因为有一部需要查前序遍历中的根节点在中序遍历中的位置,以此划分左右子树
        for(int i=0;i<po.length;i++)
            dict.put(inorder[i],i);
        return recur(0,0,inorder.length-1);
    }

    public TreeNode recur(int pre_root,int in_left,int in_right){
        //递归退出条件为左大右
        if(in_left>in_right) return null;
        var ans = new TreeNode(po[pre_root]);
        //由前序遍历得到的根节点,查到该节点在中序遍历内的索引,即可借此在中序遍历中划分出左右子树。
        int in_root = dict.get(po[pre_root]);

        //在in_left,in_root,in_right中划分
        //左子树
        ans.left = recur(pre_root+1,in_left,in_root-1);

        //右子树的根节点为 原根节点 + 左子树长度 + 1
        ans.right=recur(in_root-in_left+pre_root+1,in_root+1,in_right);
        return ans;
    }
}

原文地址:https://www.cnblogs.com/Jun10ng/p/12345257.html

时间: 2024-10-09 12:22:21

(难)【07】根据前序,中序遍历重建二叉树的相关文章

前序遍历和中序遍历重建二叉树

对于二叉树,在此我不做过多讲解,如有不懂,请参照一下链接点击打开链接 1.在此二叉树的定义: struct BinaryTreeNode     {         BinaryTreeNode<T> *_Left;         BinaryTreeNode<T> *_Right;         T _data;     public:         BinaryTreeNode(const T& x)             :_Left(NULL)       

根据先序遍历中序遍历重建二叉树

根据先序遍历和中序遍历的特点,我们想到了采用递归的方法来实现. 思路:1) 代码的容错性检查,比如:先序遍历和中序遍历长度应相等 2) 先保存先序遍历的第一个点,这个点为结点,接下来循环中序遍历,直到midOrd[index]=该结点,那么接下来就可以采用递归,分别对结点左边和右边的序列采用相同的方法. 3) 直到中序遍历中的序列中只含一个点,整个过程结束. 下面是我写的代码,一直显示错误,不知道什么原因. // 先序中序重建二叉树.cpp : Defines the entry point f

根据二叉树的前序遍历和中序遍历重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(

二叉树(14)----由前序遍历和中序遍历重建二叉树

1.二叉树定义 typedef struct BTreeNodeElement_t_ { void *data; } BTreeNodeElement_t; typedef struct BTreeNode_t_ { BTreeNodeElement_t *m_pElemt; struct BTreeNode_t_ *m_pLeft; struct BTreeNode_t_ *m_pRight; } BTreeNode_t; 二.根据前序遍历序列和中序遍历序列重建二叉树 算法说明: 由中序遍历序

七:重建二叉树(根据先序遍历(或者后序遍历)和中序遍历重建二叉树)

对于一颗二叉树,可以根据先序遍历(或者后序遍历)和中序遍历(树中不含重复的数字)重新还原出二叉树. 解析: 1. 先序遍历序列的第一个元素必定是根节点,可以由此获取二叉树的根节点. 2. 根据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列必定在根节点的左子树中,而根节点右边的序列必定在右子树中.由此可以知道先序遍历中左子树以及右子树的起止位置. 3. 找到了左右子树前序遍历和中序遍历再用同样的方法分别构建左右子树,典型的递归思想. 代码如下: Binary

七:重建二叉树(依据先序遍历(或者后序遍历)和中序遍历重建二叉树)

对于一颗二叉树.能够依据先序遍历(或者后序遍历)和中序遍历(树中不含反复的数字)又一次还原出二叉树. 解析: 1. 先序遍历序列的第一个元素必然是根节点,能够由此获取二叉树的根节点. 2. 依据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列必然在根节点的左子树中.而根节点右边的序列必然在右子树中.由此能够知道先序遍历中左子树以及右子树的起止位置. 3. 找到了左右子树前序遍历和中序遍历再用相同的方法分别构建左右子树,典型的递归思想. 代码例如以下: Bin

利用层序遍历(不含None)和中序遍历重建二叉树 python

给定一颗二叉树的层序遍历(不含None的形式)和中序遍历序列,利用两个序列完成对二叉树的重建. 还是通过一个例子来说明整个过程,下图所示的二叉树,层序遍历结果为[a,b,c,d,e],中序遍历结果为[d,b,a,c,e],我们知道当我们找到根节点后,中序遍历能够提供给我们的信息就是左右子树分别包含哪些节点,而我们能否在层序遍历中找到根节点呢?很明显,层序遍历序列的第一个点是根节点,在中序遍历中找到左右子树分别包含哪些节点之后,我们就可以在层序遍历中区分出左右子树的层序遍历结果,然后就可以分别开始

已知前序中序,重建二叉树,输出后序

具体算法就是用前序的第一个字母(根节点)去中序查找该字母,把中序分成前后2节,前一节是左子树,长度len_l,后一节是右子树,长度len_r.且前序字符串的长度也可以根据前序分析得到的长度len_l和len_r分成这样的2节.接着递归构建. 如://前序序列 "ABDHLEKCFG"; //中序序列 "HLDBEKAFCG"; 1. 用A去中序序列查找,将其分为HLDBEK和FCG,左子树的长度为6,右子树长度为3.2. 把前序序列从A之后根据上句的左右子树的长度分

根据二叉树的先序和中序遍历重建二叉树

#include <iostream> #include <cstdio> using namespace std; typedef struct BiTNode { int data; struct BiTNode *lchild, *rchild; }BiTNode, *BiTree; BiTree PreInCreate(char A[], char B[], int l1, int h1, int l2, int h2) { BiTNode *root = (BiTNode