输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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; }