题目:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输出的前序遍历和中序遍历的结果都不含有重复的数字。前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5
二叉树节点的定义如下:
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
分析
前序: a b d c e f
中序: d b a e c f
前序遍历的每一个节点,都是当前子树的根节点,同时,以对应的节点
为边界,就会把前序遍历的结果分为左子树和右子树。
a是前序中第一个节点,以a为中界,把中序的结果分成:
左:db
右:ecf
对于db,由于在前序中b在d前面,所以,b是d的父亲。
对于ecf,前序中c在前面,c为父亲,c把e和f分开。
代码如下:
TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin, int &size,int left, int right) //size标志着已经访问前序的第几个元素了。left和right标志着左闭右开。
{
int i = left;
for ( ; i < right; ++i)
{
if(pre[size] == vin[i])
break;
}
if(i == right)
{
return NULL;
}
TreeNode *root = NULL;
root = new TreeNode(pre[size]); //创建根节点
if(left < i) //有区间的都应该检查区间范围。防止越界。
{
root->left= reConstructBinaryTree(pre, vin,++size,left, i);
}
if(i+1 < right)
{
root->right= reConstructBinaryTree(pre, vin,++size,i+1,right);
}
return root;
}
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin)
{
if(pre.empty() || vin.empty() || pre.size() != vin.size())
return NULL;
int size =0;
return reConstructBinaryTree(pre, vin, size,0,pre.size());
}