40.前序和中序遍历重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。

假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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;
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章