原文链接
剑指offer 重建二叉树
分析:
如图所示,先在中序中找到根节点的位置inRootpos,然后根节点左边递归地生成左子树,根节点右边递归地生成右子树.
其中preRootpos是逐一右移的.
#include
#include
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x):val(x),left(NULL),right(NULL)
{}
};
class Solution
{
public:
struct TreeNode* reConstructBinaryTree(vector pre,vector in)
{
if(pre.size()!=in.size()||pre.size()==0||in.size()==0)return NULL;
else
{
TreeNode* inRoot=createTreeHelper(pre,in,0,0,in.size()-1);
return inRoot;
}
}
TreeNode* createTreeHelper(vector pre,vector in,int preRootpos,int inLeft,int inRight)
{//pre:前序,in:中序,preRootpos:前序中的根节点,inLeft:中序中的左边界,inRigth:中序中的右边界
int inRootpos,RootVal;
RootVal=pre[preRootpos];//根节点的值
//不建议使用.at()取下标的值
if(inLeft>inRight) return NULL;
for(int i=inLeft;i<=inRight;i++)
{
if(in[i]==RootVal)
{
inRootpos=i;
//找到根节点在中序中的位置
//for循环中循环完成后增量i无法使用,于是全局变量存储下来
}
}
int leftLen=inRootpos-inLeft;//这里的inRootpos是中序中根节点的位置
//leftLen为根节点距离左边界的长度
//即左子树的长度
//右子树的的根节点的位置就是 preRootpos+左子树的长度+1
TreeNode* inRoot=new TreeNode(RootVal);
inRoot->left=createTreeHelper(pre,in,preRootpos+1,inLeft,inRootpos-1);
inRoot->right=createTreeHelper(pre,in,preRootpos+leftLen+1,inRootpos+1,inRight);
return inRoot;
}
};
void Intraverse(TreeNode *pRoot)
{
if(pRoot == NULL) return ;
Intraverse(pRoot->left);//遍历左子树
cout<val<<" ";//访问根节点
Intraverse(pRoot->right);//遍历右子树
}
void PostTraverse(TreeNode *pRoot)
{
if(pRoot == NULL) return ;
PostTraverse(pRoot->left);//后序遍历左子树
PostTraverse(pRoot->right);//后序遍历右子树
cout<val<<" ";//访问根节点
}
int main()
{
int arrA[8]={1,2,4,7,3,5,6,8};
int arrB[8]={4,7,2,1,5,3,8,6};
vector a(arrA,arrA+8);
vector b(arrB,arrB+8);
Solution sol;
TreeNode *root;
root =sol.reConstructBinaryTree(a,b);
PostTraverse(root);
return 0;
//测试成功
//前序遍历为1 2 4 7 3 5 6 8
//中序遍历为4 7 2 1 5 3 8 6
//后序遍历输出为7 4 2 5 8 6 3 1
/*
1
2 3
4 5 6
7 8
其中4是2的左节点
7是4的右节点
5是3的左节点
6是3的右节点
8是6的左节点
*/
}
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector pre,vector vin) {
if(pre.size()!=vin.size()|| pre.size()<=0||vin.size()<=0 )
{
return NULL;
}
else
{
TreeNode* inRoot=createTree(pre,vin,0,0,vin.size()-1);//用inroot 就过不了
return inRoot;
}
}
TreeNode* createTree(vector pre,vector vin,int preroot,int vinleft,int vinright)
{
int vinroot,rootval;
rootval=pre[preroot];//根节点的值
for(int i=vinleft;i<=vinright;i++)
{
if(vin[i]==rootval)
{
vinroot=i;
}
}
if(vinleft>vinright) return NULL;
int leftlen=vinroot-vinleft;//计算的是中序里面从根节点到最左侧的距离 这里千万不能拿先序的根节点来计算
TreeNode *inRoot=new TreeNode(rootval);
inRoot->left=createTree(pre,vin,preroot+1,vinleft,vinroot-1);
inRoot->right=createTree(pre,vin,preroot+leftlen+1,vinroot+1,vinright);
return inRoot;
}
};