输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路1:前序序列第一个节点即为二叉树的根节点,以此根节点为中序序列中的分界点,分离出左子树和右子树,递归创建二叉树。
代码:
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
//若前序和中序为空,则返回空树
if(pre.empty()||vin.empty())
return NULL;
//创建根节点
TreeNode *tRoot=new TreeNode(pre[0]);
//在中序序列中找到根节点的位置,并记录左子树节点的数量
int num_lchild;
for(int i=0;i<vin.size();i++)
{
if(vin[i]==pre[0])
{
num_lchild=i;
break;
}
}
//若找到最后都没有找到对应的根节点,说明输入序列有问题
if(vin[num_lchild]!=pre[0])
return NULL;
//若找到,则可以根据此根节点划分左右子树
//递归构造左右子树
vector<int> left_pre,right_pre,left_in,right_in;
for(int i=0;i<num_lchild;i++)
{
left_pre.push_back(pre[i+1]);
left_in.push_back(vin[i]);
}
for(int i=num_lchild+1;i<vin.size();i++)
{
right_pre.push_back(pre[i]);
right_in.push_back(vin[i]);
}
//递归,再对其进行上述所有步骤,即再区分子树的左、右子子数,直到叶节点
tRoot->left=reConstructBinaryTree(left_pre,left_in);
tRoot->right=reConstructBinaryTree(right_pre,right_in);
return tRoot;
}
};注意几点:
- 特殊处理:取根节点之前,判断前序和中序序列是否为空,若为空则返回空树;
取根节点之后,遍历中序序列找出根节点的位置时,出现找不到对应节点的情况。 - 创建根节点时:TreeNode *tRoot=new TreeNode(pre[0]);里面的pre[0]相当于初始化tRoot->value=pre[0]的意思,具体情况根据节点定义确定。
- 构造左右子树前中序序列时注意区间划分。
- 别忘了返回值return tRoot.
2.递归算法:
思路都一样
TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) {
if (pre.size() == 0 || vin.size() == 0)
return nullptr;
return reConstructBinaryTree(pre, 0, pre.size() - 1, vin, 0, vin.size() - 1);
}
TreeNode* reConstructBinaryTree(vector<int> &pre, int begin_pre, int end_pre, vector<int> &vin, int begin_vin, int end_vin)
{
if (begin_pre>end_pre||begin_vin > end_vin)
return nullptr;
int rootVal = pre[begin_pre];
TreeNode* root = new TreeNode(rootVal);
int in = begin_vin;
while (vin[in]!=rootVal&&in<=end_vin)
{
++in;
}
//根据在中序找到的根节点,可以判断出左子树的元素个数为in-begin_vin。由此可以得出左右子树的起始点和终点
root->left = reConstructBinaryTree(pre, begin_pre + 1, begin_pre + in-begin_vin, vin, begin_vin, in - 1);
root->right = reConstructBinaryTree(pre, begin_pre + in + 1-begin_vin, end_pre, vin,in + 1, end_vin);
return root;
}
京公网安备 11010502036488号