Leetcode041--两种方式构建二叉树

一、原题



Given preorder and inorder traversal of a tree, construct the binary tree. 
Note: 
You may assume that duplicates do not exist in the tree. 


一、中文



一种是根据前序和中序来构建二叉树,一种是根据中序和后序来构建二叉树



三、举例



(1)给出先序遍历的一个数组和中序的一个数组,最后得到一个二叉树

(2)给出中序和后序两个数组,最后得到一个二叉树


四、思路



 
两种方式是差不多的

(1)前序和中序

前序的第一个结点就是根节点,我们可以拿到这个结点的值,在中序的数组中寻找到这个结点,那么在中序中这个结点左边的就是左子树,右边的就是右子树,然后再分别对左子树和右子树进行这样的递归操作,最终就可以得到我们的整个树了。

要注意的是要明确递归的结束条件。



(2)中序和后序

这个和后面差不多,只不过后序遍历树的根节点是在最后边的,我们同样可以拿到这个结点在中序中进行对比。然后进行递归的操作。



五、程序

 


package code;


class TreeNode5{
	int val;
	TreeNode5 left;
	TreeNode5 right;
	TreeNode5(int x){
		val = x;
	}
}

//		______7______
//		/    		 \
//		10            2
//	    /   \        /
//	   4    3      8
//		     \    /
//		      1  11

public class LeetCode56{
	public static void main(String args[]){
		int[] preorder = {7, 10, 4, 3, 1, 2, 8, 11};  
		int[] inorder = {4, 10, 3, 1, 7, 11, 8, 2};  
		int[] postorder = {4, 1, 3, 10, 11, 8, 2, 7};
		
//		TreeNode5 root = ConstructCore(preorder, inorder, 
//				0, preorder.length - 1, 
//				0, inorder.length - 1);
		
		TreeNode5 root = ConstructCore2(postorder, inorder, 
				0, postorder.length - 1, 
				0, inorder.length - 1);
		
		inorder(root);
		System.out.println();
		preorder(root);
		System.out.println();
		postorder(root);
		
	}


	//通过前序遍历和后序遍历构造二叉树
	public static TreeNode5 ConstructCore(int[] preOrder, int[] inOrder, 
			int startPreorder, int endPreorder,
            int startInorder, int endInorder){
        if (startPreorder > endPreorder || startInorder > endInorder) {
            return null;
        }
        
        TreeNode5 root = new TreeNode5(preOrder[startPreorder]);

        int divider = 0;
        
        while(divider < endInorder && inOrder[divider] != root.val){
        	divider++;
        }
        
        int offSet = divider - startInorder - 1;
        
        root.left = ConstructCore(preOrder, inOrder, 
        		startPreorder+1, startPreorder+1+offSet, 
        		startInorder, divider - 1);
        
        root.right = ConstructCore(preOrder, inOrder, 
        		startPreorder + offSet + 2, endPreorder,
        		divider + 1, endInorder);
        
        return root;
	}
	
	
	
	//通过中序遍历和后序遍历构造二叉树
	public static TreeNode5 ConstructCore2(int[] postOrder, int[] inOrder, 
			int startPostorder, int endPostorder,
            int startInorder, int endInorder){
		
        if (startPostorder > endPostorder || startInorder > endInorder) {
            return null;
        }
		
        TreeNode5 root = new TreeNode5(postOrder[endPostorder]);
        int divider = 0;
        
        while(divider < endInorder && inOrder[divider] != root.val){
        	divider++;
        }
        
        int offSet = divider - startInorder - 1;
        
        root.left = ConstructCore2(postOrder, inOrder, 
        		startPostorder, startPostorder + offSet,
        		startInorder, divider - 1);
        		
        
        root.right = ConstructCore2(postOrder, inOrder, 
        		startPostorder + offSet + 1, endPostorder - 1,
        		divider + 1, endInorder);
        
        return root;
	}
	
	
	
    // 中序遍历二叉树
    public static void inorder(TreeNode5 root) {
        if (root != null) {
            inorder(root.left);
            System.out.print(root.val + " ");
            inorder(root.right);
        }
    }

    // 先序遍历二叉树
    public static void preorder(TreeNode5 root) {
        if (root != null) {
            System.out.print(root.val + " ");
            preorder(root.left);
            preorder(root.right);
        }
    }
    
    //后序遍历二叉树
    public static void postorder(TreeNode5 root){
    	if(root != null){	
    		postorder(root.left);
    		postorder(root.right);
    		System.out.print(root.val + " ");
    	}
    }
	
}
	


--------------------------------------------------output------------------------------------------------------------

这个后序和中序构造的结果
4 10 3 1 7 11 8 2 
7 10 4 3 1 2 8 11 
4 1 3 10 11 8 2 7 







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值