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;
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章