输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
首先简单了解一下二叉树的重建,如题,给定前序和中序遍历,将二叉树建立起来并返回。意思是返回二叉树的头结点,且二叉树的子树也构建好了。我们都知道,二叉树的前序遍历是中、左、右;中序遍历是左、中、右。也就是说在前序遍历里面出现的第一个字肯定是头结点,而这个字出现在中序遍历前面的字符串肯定是这个头结点的左孩子。如下剑指offer里面:
接下来在所有的左子树中,再发现先序的第一个字符,然后确定中序中左子树所在的位置,这样就构成了递归。
先看python代码
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
if len(pre) == 0:
return None
else:
root = TreeNode(pre[0])
post = tin.index(pre[0]) #发现先序中第一个字符在中续重出现的位置
root.left = self.reConstructBinaryTree(pre[1:post+1], tin[:post])#将先序和中序的左子树放进去
root.right = self.reConstructBinaryTree(pre[post + 1:], tin[post+1:])
return root
# write code here
再看c++代码
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if (pre.size() == 0){
return NULL;
}
int i;
TreeNode* head = new TreeNode(pre[0]);
//TreeNode* head=new TreeNode(pre[0]);
int post ;
for( i=0;i<pre.size();i++){//为了找出先序中第一个数字出现在中序中的位置
if (vin[i] == pre[0])
post = i;
}
vector<int> preleft,preright,vinleft,vinright;//定义先序中序,因为我们需要把vector中的值拿出来
for (i=1;i<=post;i++){
preleft.push_back(pre[i]);//先序中的左子树
vinleft.push_back(vin[i-1]);//中序中的左子树
}
for(i=post+1;i<pre.size();i++){
preright.push_back(pre[i]);//先序中的右字树
vinright.push_back(vin[i]);//中序中的右子树
}
head->left = reConstructBinaryTree(preleft, vinleft); //递归
head->right = reConstructBinaryTree(preright,vinright);
return head;
}
};