题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
明确:
1.二叉树的前序遍历序列中,第一个值是树的根结点的值。在中序遍历序列中,根结点的值在中间,左边是左子树的结点值,右边是右子树的结点值。
2.把序列划分为三部分,在二叉树的前序遍历和中序遍历中确定根结点的值、左子树结点的值和右子树结点的值。构建出根结点。
3.然后用同样的方法构建左子树和右子树,就要用递归。
思路:
ConstructBinaryTree()函数先根据先序遍历序列的第一个数字创建根结点,再从中序遍历序列中找到根结点的位置,确定出左子树和右子树结点的数量。在先序序列和中序序列中划分左子树和右子树结点的区间后,递归调用ConstructBinaryTree()函数,分别构建左右子树。
代码:
/**
* 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||vin.size()==0)
return nullptr;
return ConstructBinaryTree(pre,0,pre.size()-1,vin,0,vin.size()-1);
}
TreeNode * ConstructBinaryTree(vector<int> pre,int preBegin,int preLast,
vector<int> vin,int vinBegin,int vinLast)
{
TreeNode *root=new TreeNode(pre[preBegin]);//构建当前根结点
root->left=root->right=nullptr;
if(preBegin==preLast)//递归出口,当前结点是叶子结点时返回
return root;
int vinMidRoot=vinBegin;//遍历中序序列中找根结点的位置
for(int i=vinBegin;i<=vinLast;i++)
{
if(pre[preBegin]==vin[i])
{
vinMidRoot=i;
break;
}
}
int leftLength,rightLength;
leftLength=vinMidRoot-vinBegin;//当前结点的左子树长度
rightLength=vinLast-vinMidRoot;//当前结点的右子树长度
if(leftLength>0)//有左子树
root->left=ConstructBinaryTree(pre,preBegin+1,preBegin+leftLength,vin,vinBegin,vinMidRoot-1);
if(rightLength>0)//有右子树
root->right=ConstructBinaryTree(pre,preBegin+1+leftLength,preLast,vin,vinMidRoot+1,vinLast);
return root;
}
};