您的位置:首页 > 其它

重建二叉树

2017-07-02 21:43 204 查看

引言

这两天偶然看到一道题,应该是《剑指offer》上的,原题如下:

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

解题思路

在解题之前我们需要知道前序,中序,后序是怎么遍历的,这里不多做介绍。我们将前序遍历序列设为pre,中序遍历序列设为vin。

1. 首先我们需要确定根节点,很简单,就是前序遍历的第一个元素pre[0]=1;

2. 因为对于中序遍历,根节点左边的节点位于二叉树的左边,根节点右边的节点位于二叉树的右边



这样我们就把整个序列分为了两部分,{4,7,2}在根节点的左边,{5,3,8,6}在根节点的右边

3. 针对{4,7,2},{5,3,8,6}分别重复执行第二步,直到所有节点都分配完毕,具体步骤如下:

3.1 对于{4,7,2},查看前序遍历序列{1,2,4,7,3,5,6,8},发现1后面的节点为2,也就是说2为{4,7,2}这个左分支的根节点;



注意上图中此时没有右树

3.2 依次类推,直接上图;



3.3 对于{5,3,8,6}重建的方法和左树一样,直接上图;



3.4 每一步其实就是利用前序遍历序列找到根节点,再利用中序遍历序列将左右子树分开,最后再合并起来;



代码

将解题思路总结为代码,如下:

TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin)
{
int inlen=vin.size();

if(pre.empty() || vin.empty()) return NULL;
else if(inlen != pre.size()) return NULL;

vector<int> left_pre,right_pre,left_in,right_in;

//创建根节点,根节点为前序遍历的第一个元素
TreeNode* head=new TreeNode(pre[0]);

//找到中序遍历根节点所在位置,存放于变量gen中
int gen=0;
for(int i=0;i<inlen;i++)
{
if (vin[i]==pre[0])
{
gen=i;
break;
}
}

//对于中序遍历,根节点左边的节点位于二叉树的左边,根节点右边的节点位于二叉树的右边
for(int i=0;i<gen;i++) //找到左树
{
left_in.push_back(vin[i]);
left_pre.push_back(pre[i+1]);
}

for(int i=gen+1;i<inlen;i++) //找到右树
{
right_in.push_back(vin[i]);
right_pre.push_back(pre[i]);
}

//递归,划分子树的左、右树,直到叶节点
head->left=reConstructBinaryTree(left_pre,left_in);

head->right=reConstructBinaryTree(right_pre,right_in);

return head;
}

代码比较简单,但是还是让我们来看看大神的code(java):
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
//前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {

if(startPre>endPre||startIn>endIn)
return null;
TreeNode root=new TreeNode(pre[startPre]);

for(int i=startIn;i<=endIn;i++)
if(in[i]==pre[startPre]){
root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
root.right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);
}

return root;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: