如题:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和
中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序
遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
根据前序和中序数列重建二叉树,这道题,还有一道类似题,根据后续和中序数列重建二叉树。两题解法完全一样,仅仅方向不同。这是学习二叉树的时候必做的题型,和遍历二叉树性质类似。
看题,我们知道,前序遍历得到的数列,依次是各子树的根节点,如根节点,根节点左子树,根节点右子树......,此外,中序遍历数列中,根节点的值位于中间,左右两边依次是左右子树。结合前序数列性质,我们可以这样做,先再前序数列求得根节点的值,然后,查找中序遍历,此时,中序数列中,位于根节点左边的数列即是左子树,右边的为右子树。先后求得根节点的左子树以及右子树。之后,采用递归,依次求得节点的左右子树即可。
后序遍历也是一样处理,只不过方向变反。后序遍历数列,从后往前依次是根节点,根节点右子树,根节点左子树,即左右子树求取顺序和上述题型相反。
下面是本题的c++解法:
//模板题,先计算根节点,然后分别计算左子树和右子树的根节点
class Solution {
public:
TreeNode *constructTree(vector<int> pre,int *preStart, int preEnd, vector<int> vin, int vinStart, int vinEnd){
int i;
TreeNode *root;
//特殊情况处理
if (vinStart > vinEnd) return NULL;
root = new TreeNode(pre[*preStart]);
//找到左子树和右子树的范围
for (i = vinStart; i <= vinEnd; i++){
if (pre[*preStart] == vin[i])
break;
}
//指向下一个根节点
*preStart = *preStart + 1;
root->left = constructTree(pre, preStart, preEnd, vin,vinStart,i-1);
root->right = constructTree(pre, preStart, preEnd, vin,i+1, vinEnd);
return root;
}
TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) {
int preStart = 0;
if (pre.empty()) return NULL;
return constructTree(pre, &preStart, pre.size()-1,vin,0,vin.size()-1);
}
};
=============================================================================================
Linux应用程序、内核、驱动、后台开发交流讨论群(745510310),感兴趣的同学可以加群讨论、交流、资料查找等,前进的道路上,你不是一个人奥^_^。