题目描述:
根据前序遍历和中序遍历树构造二叉树
注意事项:
你可以假设树中不存在相同数值的节点
样例:
给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树:
思路讲解:
由于是先序遍历,所以这个数组得第一个一定是其根节点,然后根据中序遍历可以将根节点得左右节点的内容得到,然后递归调用,就可以将这棵树建立起来。
例如:
前序遍历为1245367
中序遍历为4251637
首先我们根据前序遍历得到这棵树的根节点是1,然后通过中序遍历得到左边的是425,右边的是637,递归一下 前序遍历是245 中序遍历是425,由于前序遍历中2在最前面,故2是根节点,即2是1的左节点,4是2的左节点,5是2的右节点。然后 右边的 前序遍历是367,中序遍历是637,这样由于3在前面,所以3是1的右节点,6是3的左节点,7是3的右节点。
代码详解:
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
/**
*@param preorder : A list of integers that preorder traversal of a tree
*@param inorder : A list of integers that inorder traversal of a tree
*@return : Root of a tree
*/
public:
TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
// write your code here
TreeNode * root;
if(preorder.size()==0)
{
root=NULL;
return root;
}
int rootNode=preorder[0];
int index=findpos(inorder,rootNode);
vector<int>left_inorder;
vector<int>right_inorder;
for(int i=0;i<index;i++)//左节点的中序遍历
{
left_inorder.push_back(inorder[i]);
}
for(int i=index+1;i<inorder.size();i++)//右节点的中序遍历
{
right_inorder.push_back(inorder[i]);
}
vector<int>left_preorder;
vector<int>right_preorder;
for(int i=1;i<index+1;i++)//左节点的前序遍历
{
left_preorder.push_back(preorder[i]);
}
for(int i=index+1;i<preorder.size();i++)//右节点的前序遍历
{
right_preorder.push_back(preorder[i]);
}
root=new TreeNode();
if(root!=NULL)
{
root->val=rootNode;
root->left=buildTree(left_preorder,left_inorder);
root->right=buildTree(right_preorder,right_inorder);
}
return root;
}
int findpos(vector<int> inorder,int node)//找到根节点在中序遍历中的位置
{
for(int i=0;i<inorder.size();i++){
if(inorder[i]==node){
return i;
}
}
return 0;
}
void printvector(vector<int> m)
{
for(int i=0;i<m.size();i++)
{
cout<<m[i]<<" ";
}
cout<<endl;
}
void PreOrderTraverse(TreeNode * t) //验证结果
{
if(t!=NULL)
{
cout<<t->val;
PreOrderTraverse(t->left);
PreOrderTraverse(t->right);
}
}
};