剑指Offer第四题:重构二叉树
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
题目分析
依据我们平时根据前序和中序构建二叉树的经验,我们一般都是在前序序列里面的第一个开始寻找,第一个就是我们的根节点,然后根据前序序列的第一个数在中序序列中遍历到它的位置,遍历到它的位置后,我们把他左边的当做一颗新的二叉树,再由相同的方法从前序序列中寻找节点。
算法分析
- 根据前序序列和中序序列构建二叉树,应该参照前序序列遍历中序序列寻找节点
- 代码重构和平时的作业不一样,我们要以机器的角度来解决问题,我们在由前序序列来遍历中序序列的时候,将该节点的中序序列的左边和右边分成两颗小得二叉树。
- 需要用到递归对根节点的回溯
源代码
1 class TreeNode {//定义节点就没有多解释的余地了 2 int val; 3 TreeNode left; 4 TreeNode right; 5 TreeNode(int x) { val = x; } 6 } 7 public class Solution { 8 public TreeNode reConstructBinaryTree(int [] pre,int [] in) { 9 10 int start_pre=0; 11 int end_pre=pre.length-1; 12 int start_in=0; 13 int end_in=in.length-1; 14 15 16 return BinaryTree(pre, in, start_pre, end_pre, start_in, end_in); 17 //由于我们是要用递归来解决问题,那么参数就比较重要,往往是递归终止的条件 18 } 19 } 20 private TreeNode BinaryTree(int []pre,int []in,int start_pre,int end_pre,int start_in,int end_in) { 21 22 if(start_pre>end_pre||start_in>end_in) //只要满足这个条件那么递归结束 23 return null; 24 TreeNode node=new TreeNode(pre[start_pre]);//我们将每次遍历的第一个前序序列作为根节点 25 26 for(int i=start_in;i<=end_in;i++) {//遍历中序序列 27 if(in[i]==pre[start_pre]) { 28 node.left=BinaryTree(pre, in, start_pre+1, start_pre+i-start_in, start_in, i-1); 29 //这里的参数变化,start_pre+1表示在前序序列已经向前遍历了一位,故向前+1,下一个参数:现在我们先遍历的是根节点的左子树,那么我们需要确定 30 //根节点的左子树在前序序列的是前那几个数。故start_pre+i-start_in,最后一个参数表示中序序列的结束位置,就上一句话已经说了,我们先遍历左子 31 //树,那么中序序列的左子树的标记那么就是i-1. 32 node.right=BinaryTree(pre, in, i-start_in+start_pre+1, end_pre, i+1, end_in); 33 //这里的参数变化:由于这部分是关于右子树,那么我们需要控制,前序序列开始的位置(因为前面的数已经被左子树遍历完了),i+1就是中序序列向后遍历了一位 34 break; 35 } 36 } 37 38 39 return node; 40 41 42 }
运行截图
ps:转载请标明出处,多有不足多多指教