题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解析:
①首先根据前序遍历可知,前序序列的第一个元素为根节点,即1为根节点;
②在中序遍历序列中找到1所在的位置,1之前的序列为左子树,即{4,7,2}为根节点的左子树。1之后的序列为右子树,即{5,3,8,6}为根节点的右子树;
③左子树{4,7,2}对应前序遍历中的[2,4,7},所以2为根节点,右子树{5,3,8,6}对应前序遍历中的{3,5,6,8},所以5为根节点;
④重复②③步骤,即进入递归求解。
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if (pre == null || in == null) return null;
TreeNode root = null;
root = rebuild (pre,0,pre.length-1,in,0,in.length-1);//重建二叉树
return root;
}
//核心递归函数
public TreeNode rebuild(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]){//pre[startpre]为根,找出其对应在中序遍历in中的根元素
//对根节点的左子树进行递归操作,注意此时根节点的位置
root.left = rebuild(pre,startpre+1,startpre+i-startin,in,startin,i-1);
//对根节点的右子树进行递归操作
root.right = rebuild(pre,startpre+i-startin+1,endpre,in,i+1,endin);
}
}
return root;
}
拓展:中序 后序遍历构造二叉树
操作跟上面一样
public TreeNode buildTree(int[] inorder, int[] postorder) {
if (inorder == null || postorder == null) return null;
TreeNode root = null;
root = buildTree(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
return root;
}
public TreeNode buildTree(int[] inorder,int startin,int endin,int[] postorder,int startpost,int endpost){
if (startin > endin || startpost > endpost) return null;
TreeNode node = new TreeNode(postorder[endpost]);
for (int i = startin; i <= endin;i++){
if (inorder[startin] == postorder[endpost]){
node.left = buildTree(inorder,startin,i-1,postorder,startpost,i-startin-1+startpost);
node.right = buildTree(inorder,i+1,endin,postorder,i-startin+startpost,endpost-1);
}
}
return node;
}