首页 > 试题广场 >

从中序和后序遍历构造二叉树

[编程题]从中序和后序遍历构造二叉树
  • 热度指数:16945 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
给出一棵树的中序遍历和后序遍历,请构造这颗二叉树
注意:
保证给出的树中不存在重复的节点
示例1

输入

[2,1,3],[2,3,1]

输出

{1,2,3}

说明:本题目包含复杂数据结构TreeNode,点此查看相关信息
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     *
     * @param inorder int整型一维数组
     * @param postorder int整型一维数组
     * @return TreeNode类
     */
    public TreeNode buildTree (int[] inorder, int[] postorder) {
        // write code here

        //e []  arr = Arrays.copyOfrange(arr,from,to);
        //注意一下to并不包含
        //递归出口
        if (inorder.length == 0) return null;

        //在后序遍历序列寻找当前Tree的根节点,并建立当前树根
        int postRight = postorder.length - 1;
        TreeNode root  = new TreeNode(postorder[postRight]);
        //根据树根和中序序列,寻找到左子树和右子树
        int indexRoot = 0;
        for (int i = 0; i < inorder.length; i++) {
            if (inorder[i] == postorder[postRight]) {
                indexRoot = i;
                break;
            }
        }
        int [] newLeftPostorder = Arrays.copyOfRange(postorder,0,indexRoot);
        int [] newLeftInorder = Arrays.copyOfRange(inorder,0,indexRoot);
        int [] newRightInorder = Arrays.copyOfRange(inorder,indexRoot+1,postRight+1);
        int [] newRightPostorder = Arrays.copyOfRange(postorder,indexRoot,postRight);  
        //递归建立左右子树的根节点(也就是当前树根的左右孩子)
        root.left = buildTree (newLeftInorder, newLeftPostorder);
        root.right = buildTree (newRightInorder, newRightPostorder);
        return root;   
    }

}


发表于 2022-08-22 07:54:59 回复(1)
/**
总结
中序和后序的规律是
同为长为n的序列
长为k的左子树 根 长为n-k-1的右子树
长为k的左子树 长为n-k-1的右子树 根

1、确定两个序列中根所在的位置后
2、截出两个左子树序列,继续找左子树的根,将其作为上一根节点的左节点
2、截出两个右子树序列,继续找右子树的根,将其作为上一根节点的右节点
3、递归找根,知道子树为空时结束

**/

public class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(postorder==null||postorder==null){
            return null;
        }
        return travel(inorder,postorder,0 , inorder.length-1 , 0,postorder.length-1);
    }
    public TreeNode travel(int[] inorder, int[] postorder , int inx,int iny ,int postx , int posty){
        if(inx>iny || postx>posty){
            return null;
        }
        TreeNode node = new TreeNode(postorder[posty]);
        
        for (int k = 0 ; inx+k<=iny ; k++){ 
        //注:最好用0,若用inx作为起始,需要减去inx得到相对长度来截取后序遍历。
            if(inorder[inx+k]==postorder[posty]){
                node.left = travel(inorder,postorder,inx , inx+ k-1 , postx,postx+ k-1);
                node.right = travel(inorder,postorder,inx+ k+1 , iny , postx+ k,posty-1);
                
            }
        }
        return node;
    }
}

发表于 2020-04-25 23:07:03 回复(0)

private TreeNode build(int[] inorder,int ileft,int iright, int[] postorder, int pleft, int pright) {
if (pleft>pright||ileft>iright)
return null;
int rootVal=postorder[pright];
TreeNode root = new TreeNode(rootVal);
int rootIndex = findRoot(inorder, postorder, ileft,iright,rootVal);
root.left=build(inorder,ileft,rootIndex-1,postorder,pleft,pleft+rootIndex-ileft-1);
root.right=build(inorder,rootIndex+1,iright,postorder,pleft+rootIndex-ileft,pright-1);
return root;
}

//寻找根结点在inorder中的index
private int findRoot(int[] inorder, int[] postorder, int left, int right,int root) {
    //顺序查找
    while (left<right&&inorder[left] != root){
        left++;
    }
    return left;
}
发表于 2019-07-24 12:18:48 回复(0)
思路:先通过后序遍历找到根节点,再利用中序遍历将序列划分为左右子树。假设树的后序遍历为342651,树的中序遍历为324165,由后序遍历可知,1为根,由中序遍历可知,324为左子树,65为右子树。然后对左右子树重复以上方法,继续找出子树的根和左右子树。
public TreeNode buildTree(int[] inorder, int[] postorder) {
        TreeNode node=help(inorder, 0, inorder.length-1, postorder,0, postorder.length-1);
        return node;
    }
    public TreeNode help(int[] inorder,int inleft,int inright,int[] postorder, int postleft,int postright){
        if(postleft>postright){
            return null;
        }
        TreeNode node=new TreeNode(postorder[postright]);
        if(postleft==postright){
            return node;
        }
        int num=0;
        for(int i=inleft;i<=inright;i++){
            if(postorder[postright]==inorder[i]){
                num=i;
                break;
            }
        }
        int length=num-inleft;
        
        node.left=help(inorder, inleft,num-1,postorder,postleft,postleft+length-1);
        node.right=help(inorder, num+1,inright,postorder,postleft+length,postright-1);
        
        return node;
    }

发表于 2018-11-20 15:25:57 回复(0)

注意数组坐标的选取

public class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if (inorder == null || inorder.length == 0 || postorder == null || postorder.length == 0)
            return null;

        return build(inorder, postorder, 0, inorder.length - 1, 0, inorder.length - 1);

    }

    public TreeNode build(int[] inorder, int[] postorder, int instart, int inend, int poststart, int postend) {
        if (instart > inend || poststart > postend)
            return null;
        int rootValue = postorder[postend];
        TreeNode root = new TreeNode(rootValue);
        int indexOfRoot = -1;
        for (int i = instart; i <= inend; i++) {
            if (inorder[i] == rootValue) {
                indexOfRoot = i;
                break;
            }
        }

        root.left = build(inorder,postorder,instart,indexOfRoot - 1, poststart, poststart + indexOfRoot - instart - 1);
        root.right = build(inorder,postorder,indexOfRoot+1,inend,poststart + indexOfRoot - instart, postend-1);

        return root;
    }
}
发表于 2018-03-16 14:41:21 回复(0)
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.Arrays;
public class Solution {
    
    
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        
        if(inorder.length!=postorder.length){
            return null;
        }
        
        if(inorder.length==0){
            
            return null;
        }
        
        TreeNode root=new TreeNode(postorder[ inorder.length-1 ]);
        
        if(inorder.length==1){
            
            return root;
        }
        
        int index=0;
        
        for(int i=0;i<inorder.length;i++){
            
        if(inorder[i]==postorder[ inorder.length-1 ]) {
                
                index=i;
            break;
                
            }
            
    }
        
    root.left=buildTree(Arrays.copyOfRange(inorder,0,index),Arrays.copyOfRange(postorder,0,index));
    root.right=buildTree( Arrays.copyOfRange(inorder, index+1,inorder.length) , Arrays.copyOfRange(postorder, index,inorder.length-1) );
   
    return root;
    
    }
    
    
}
发表于 2017-08-20 20:39:25 回复(0)
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if (inorder.length == 0)
            return null;
        return buildTree(inorder, postorder, 0, inorder.length - 1, 0, postorder.length - 1);
    }
    public TreeNode buildTree(int[] inorder, int[] postorder, int inStart, int inEnd, int postStart, int postEnd) {
        if (inStart > inEnd || postStart > postEnd)
            return null;
        TreeNode root = new TreeNode(postorder[postEnd]);
        int i = inStart;
        for (i = inStart; i <= inEnd; ++i) {
            if (inorder[i] == postorder[postEnd])
                break;
        }
        TreeNode leftNode = buildTree(inorder, postorder, inStart, i - 1, postStart, postStart + (i - 1) - inStart);
        TreeNode rightNode = buildTree(inorder, postorder, i + 1, inEnd, postStart + (i - 1) - inStart + 1, postEnd - 1);
        root.left = leftNode;
        root.right = rightNode;
        return root;
    }
}

发表于 2017-08-06 22:50:56 回复(0)
public class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        return f(postorder,0,postorder.length,inorder,0,postorder.length);
    }
    public TreeNode f(int[] bh,int s,int e,int []mid,int s1,int e1){
        if(s==e) return null;
        TreeNode t = new TreeNode(bh[e-1]);
        int i=s1;
        for(;i<e1;i++)
            if(mid[i]==bh[e-1]) break;
        t.left=f(bh,s,s+i-s1,mid,s1,i);
        t.right=f(bh,s+i-s1,e-1,mid,i+1,e1);
        return t;
    }
}

发表于 2017-07-27 11:03:13 回复(0)
import java.util.*;
public class Solution {
    HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        for(int i=0; i<inorder.length; i++)
            map.put(inorder[i],i);
        return getRoot(inorder, postorder, postorder.length-1, 0, inorder.length-1);
    }
    
    public TreeNode getRoot(int[] inorder, int[] postorder, int postEnd, int left, int right) {
        if(left > right || postEnd < 0)
            return null;
        else {
            int val = postorder[postEnd];
            TreeNode root = new TreeNode(val);
            int index = map.get(val);
            root.left = getRoot(inorder, postorder, postEnd - (right - index + 1), left, index - 1);
            root.right = getRoot(inorder, postorder, postEnd - 1, index + 1, right);
            return root;
        }
    }
}

发表于 2017-06-26 13:06:44 回复(0)
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
	 public TreeNode buildTree(int[] inorder, int[] postorder) {
		if(inorder==null||postorder==null||inorder.length==0||postorder.length==0||postorder.length!=inorder.length){
			return null;
		}		 
		 return buildTree(inorder,0,inorder.length-1, postorder,0,postorder.length-1);
	 }


	private TreeNode buildTree(int[] inorder, int instart, int inend, int[] postorder, int poststart,
			int postend) {
		 if (instart>inend||poststart>postend) {
	            return null;
	        }
		TreeNode root = new TreeNode(postorder[postend]);
		for(int i=0;i<inorder.length;i++){
			if(inorder[i]==postorder[postend]){
				root.left = buildTree(inorder, instart, i-1, postorder, poststart,
						poststart+i-1-instart);
				
				root.right = buildTree(inorder, i+1, inend, postorder, poststart+i-instart,
						postend-1);
			}
		}
		
		return root;
		
		
	}
}
    


编辑于 2017-03-26 17:21:39 回复(0)
public TreeNode buildTreePostIn(int[] inorder, int[] postorder) { if (inorder == null || postorder == null || inorder.length != postorder.length) return null;
	HashMap<Integer, Integer> hm = new HashMap<Integer,Integer>(); for (int i=0;i<inorder.length;++i)
		hm.put(inorder[i], i); return buildTreePostIn(inorder, 0, inorder.length-1, postorder, 0, 
                          postorder.length-1,hm);
} private TreeNode buildTreePostIn(int[] inorder, int is, int ie, int[] postorder, int ps, int pe, 
                                 HashMap<Integer,Integer> hm){ if (ps>pe || is>ie) return null;
	TreeNode root = new TreeNode(postorder[pe]); int ri = hm.get(postorder[pe]);
	TreeNode leftchild = buildTreePostIn(inorder, is, ri-1, postorder, ps, ps+ri-is-1, hm);
	TreeNode rightchild = buildTreePostIn(inorder,ri+1, ie, postorder, ps+ri-is, pe-1, hm);
	root.left = leftchild;
	root.right = rightchild; return root;
}

发表于 2017-03-12 10:54:13 回复(0)
public class Solution {
	public TreeNode buildTree(int[] inorder, int[] postorder) {
		return createBinaryTree(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
	}

	public TreeNode createBinaryTree(int[] inorder, int inLeft, int inRight, int[] postorder, int postLeft, int postRight) {
		if(inLeft > inRight || postLeft > postRight) return null;
		TreeNode root = new TreeNode(postorder[postRight]);
		int len = 0;
		for (int i = inLeft; i <= inRight; i ++) {
			if(inorder[i] == postorder[postRight]) break;
			len ++;
		}
		root.left = createBinaryTree(inorder, inLeft, inLeft + len - 1, postorder, postLeft, postLeft + len - 1);
		root.right = createBinaryTree(inorder, inLeft + len + 1, inRight, postorder, postLeft + len, postRight - 1);
		return root;
	}
}
编辑于 2017-07-22 23:14:02 回复(0)