二叉树是数据结构中比较重要的一部分,通过给定的二叉树可以进行前序中序和后序遍历,但是反过来,如果给定前序遍历和中序遍历,是否可以重建出一棵二叉树。答案是,可以。
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
//使用vector容器作为参数
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
//判断给定的前序以及中序是否为空
if(pre.size()==0||vin.size()==0)
return NULL;
int* preStart = &pre[0]; //取前序的第一个元素地址,定义一个指针指向
int* preEnd = &pre[pre.size()-1];//取前序的最后一个元素地址,定义一个指针指向
int* vinStart = &vin[0];//取中序的第一个元素地址,定义一个指针指向
int* vinEnd = &vin[vin.size()-1];//取中序最后一个元素地址,定义一个指针指向
return ConstructTree(preStart,preEnd,vinStart,vinEnd);
}
TreeNode* ConstructTree(int* preStart,int* preEnd,int* vinStart,int* vinEnd)
{
int data = preStart[0];//取出前序的第一个数据
TreeNode* root = new TreeNode(data);//以该数据作为该重建树的根节点,因为由前序遍历的特点可知,第一个数据就是根节点
if(preStart==preEnd)
{
if(preStart == vinEnd&& preEnd==vinStart)
return root;
}
int* rootInorder = vinStart;//定义一个指针,开始遍历中序数组,直到找到根节点再停止,这样就可以分出左子树和右子树
while(rootInorder<=vinEnd && *rootInorder!=data)
++rootInorder;
if(rootInorder==vinEnd && *rootInorder!=root->val)
return NULL; //如果在中序中没有找到根节点则返回空
int leftlength = rootInorder-vinStart;
int* leftpreOrderEnd = preStart+leftlength;//根据在中序中找到的左子树就可以找出前序中的左子树
//再依次根据递归即可重建该二叉树
if(leftlength>0)
{
root->left = ConstructTree(preStart+1,leftpreOrderEnd,vinStart,rootInorder-1);
}
if(leftlength<preEnd-preStart)
{
root->right = ConstructTree(leftpreOrderEnd+1,preEnd,rootInorder+1,vinEnd);
}
return root;
}
};