数据结构:二叉树
题目:重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
**宽度优先遍历:**先访问树的第一层节点,再访问树的第二层。。。一直到访问到最下面一层节点。在同一层节点中,以左到右的顺序依次访问。我们可以对包含二叉树在内的所有树进行宽度优先遍历。
思路《剑指Offer》:在二叉树的前序遍历中,第一个数字总是树的根节点的值。但是中序遍历中,根节点的值在中间,左子树的值位于根节点的值的左边,而右子树的节点的值位于根节点的值的右边。因此我们需要扫描中序遍历序列,才能找到根节点的值。
package 重建二叉树;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class Solution {
public static TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root= reConstractBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
private static TreeNode reConstractBinaryTree(int []pre,int prestart,int preend,int[]in,int instart,int inend){
if(prestart>preend||instart > inend)
return null;
TreeNode root= new TreeNode(pre[prestart]);//注意这里时行参 所以用prestart。
for(int i=instart;i<=inend;i++){
if(pre[prestart]==in[i]){
root.left=reConstractBinaryTree(pre,prestart+1,prestart+i-instart,in,instart,i-1);
root.right=reConstractBinaryTree(pre,prestart+i-instart+1,preend,in,i+1,inend);
}
}
return root;
}
}
下面是测试程序
package 重建二叉树;
public class Test {
public static void main(String[] args) {
int [] pre = {1,2,4,7,3,5,6,8};
int [] in = {4,7,2,1,5,3,8,6};
System.out.println(Solution.reConstructBinaryTree(pre, in));
}
}
总结:我们先根据前序遍历的第一个数字创建根节点,接下来在中序遍历序列中找到根节点的位置。这样就能确定左右子树节点的数量。在前序遍历和中序遍历序列中划分了左右子树节点的值之后,我们就可以递归调用函数reConstractBinaryTree分别去构建它的左右子树。