剑指Offer:重建二叉树
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路:根据二叉树的定义。
前序遍历:1.遍历root根节点
2.前序遍历左子树
3.前序遍历右子树
根据前序遍历的结果可知第一个访问的必定是root结点。
中序遍历:1.中序遍历左子树
2.遍历root根节点
3.中序遍历右子树
根据中序遍历的结果,再结合前序遍历的root结点去划分root结点的左右子树。
后序遍历:1.后序遍历左子树
2.后序遍历右子树
3.遍历root根节点
根据后序遍历的结果可知最后访问的必定是root结点。
示例:
假如有如下的二叉树:
根据上面的定义,得出如下的遍历结果
前序遍历:ABDHIEJCFKG
中序遍历:HDIBEJAFKCG
后序遍历:HIDJEBKFGCA
由此可知根据前序遍历和中序遍历的结果则可重建二叉树
function TreeNode(x) {
this.val = x;//当前节点的数据域
this.left = null;//指针左移
this.right = null;//指针右移
}
function reConstructBinaryTree(pre, vin)
{
var root=0,i,j;
var left_pre=[],left_vin=[],right_pre=[],right_vin=[];
if(vin.length===0){
return null;
}
var head = new TreeNode(pre[0]);//pre[0]即为根节点
for(i=0;i<vin.length;i++){
if(vin[i]===pre[0]){
root=i;//从中序遍历的数组中找到根节点的位置
break;
}
}
for(j=0;j<root;j++){
left_pre.push(pre[j+1]);//左子树的前序遍历放置在left_pre数组中
left_vin.push(vin[j]);//左子树的中序遍历放置在left_vin数组中
}
for(j=root+1;j<vin.length;j++){
right_pre.push(pre[j]);//右子树的前序遍历放置在right_pre数组中
right_vin.push(vin[j]);//右子树的中序遍历放置在right_vin数组中
}
head.left= reConstructBinaryTree(left_pre,left_vin);//递归遍历左子树
head.right= reConstructBinaryTree(right_pre,right_vin);//递归遍历右子树
return head;
}