剑指offer系列——重建二叉树
Posted xym4869
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer系列——重建二叉树相关的知识,希望对你有一定的参考价值。
Q:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
C:时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
A:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if (pre.empty())
return nullptr;
try {
if(pre.size()!=vin.size())
throw -1;
}catch(int){
printf("The size of pre is not equal to the size of vin
");
}
TreeNode *tree = new TreeNode(pre[0]);
vector<int> left_pre, right_pre, left_vin, right_vin;
int inroot;
bool flag = false;
for (inroot = 0; inroot < vin.size(); inroot++) {
if (vin[inroot] == pre[0]) {
flag = true;
break;
}
}
try {
if (!flag)
throw 'e';
}catch (char){
printf("The data in pre and vin are wrong");
}
for (int i = 0; i < vin.size(); i++) {
if (i < inroot) {
left_pre.push_back(pre[i + 1]);
left_vin.push_back(vin[i]);
} else if (i > inroot) {
right_pre.push_back(pre[i]);
right_vin.push_back(vin[i]);
}
}
tree->left = reConstructBinaryTree(left_pre, left_vin);
tree->right = reConstructBinaryTree(right_pre, right_vin);
return tree;
}
A:使用递归的方法。在学习《数据结构》时,注意到如何分离left_vin和right_vin,没注意如何区分left_pre和right_pre.
前序遍历序列的第一个数字1就是根结点的值。扫描中序遍历序列,就能确定根结点的值的位置Inroot。根据中序遍历特点,在根结点Root之前的节点都是左子树结点,也就是说4 7 2就是左子树的中序遍历,而5 3 8 6就是右子树的中序遍历。同理左子树的前序遍历是2 4 7,右子树的前序遍历是3 5 6 8,然后递归就可创建二叉树。
p.s.测试:
int test() {
vector<int> pre = {1, 2, 4, 7, 3, 5, 6, 8};
vector<int> vin = {4, 7, 2, 1, 5, 3, 8, 6};
TreeNode *tree = reConstructBinaryTree(pre, vin);
return 0;
}
以上是关于剑指offer系列——重建二叉树的主要内容,如果未能解决你的问题,请参考以下文章
剑指 Offer(C++版本)系列:剑指 Offer 07 重建二叉树