二叉树:序列构造

19 篇文章 0 订阅
5 篇文章 0 订阅

目录

1、从前序与中序遍历序列构造二叉树 leetcode105

2、从中序与后序遍历序列构造二叉树 leetcode106

3、LeetCode297. 二叉树的序列化与反序列化

4、小结

 


1、从前序与中序遍历序列构造二叉树 leetcode105

       先序遍历的顺序是 root -> left -> right,中序: left -> root -> right,这就能方便的从根开始构造一棵树。

       首先,preorder 中的第一个元素一定是树的根,这个根又将 inorder 序列分成了左右两棵子树。现在我们只需要将先序遍历的数组中删除根元素,然后重复上面的过程处理左右两棵子树。先序的遍历结果决定了我们只能先创建左子树再创建右子树,借助 “队列” 数据结构将先序中根节点依次取出该方法的核心就是用先序序列元素作即根节点分割中序序列

给定二叉树结构如下:

	      1
	    /   \
	   2     3
	  / \   / \ 
	 4   5 6   7

动图创建如下:

3.gif

力扣官方题解:《已知先序和中序构造二叉树》

递归实现如下,注意终止条件:前序和中序序列为空,实际上如果给定序列是有效的,那么终止条件 中序序列一个为空就够了。

    public TreeNode buildTree(int[] preorder, int[] inorder) {

        if(preorder == null || inorder == null || preorder.length < 1 || inorder.length < 1){
            return null;
        }
        
        Queue<Integer> preorderQueue  = new LinkedList<>();
        List<Integer> inorderList =  new ArrayList<>();

        for(int i = 0; i < preorder.length; i++){
            preorderQueue.add(preorder[i]);
            inorderList.add(inorder[i]);
        }
        return buildTree(preorderQueue,inorderList);
    }
    
    private TreeNode buildTree(Queue<Integer> preorder, List<Integer>  inorder) {
    	
        if(preorder.isEmpty()|| inorder.isEmpty()){
            return null;
        }
        
        int nodeVal =  preorder.poll();
        TreeNode curNode = new TreeNode(nodeVal);
        int index =  inorder.indexOf(nodeVal);
        if(index < 0){
            return null;
        }
        
        List<Integer> letf =  inorder.subList(0,index);
        List<Integer> right = inorder.subList(index + 1,inorder.size());
        curNode.left = buildTree(preorder,letf);
        curNode.right = buildTree(preorder,right);
        
        return curNode;
    }

2、从中序与后序遍历序列构造二叉树 leetcode106

        如何根据两种遍历序列构造树:中序,和先序/后序/等等。通常从先序序列或者后序序列开始,根据不同遍历方法的规律,选择合适的节点构造树。
         先序序列的 第一个 节点是根节点,然后是它的左孩子,右孩子等等。
         后序序列的 最后一个 节点是根节点,然后是它的右孩子,左孩子等等。

        从先序/后序序列中找到根节点,根据根节点将中序序列分为左子树和右子树。从中序序列中获得的信息是:如果当前子树为空(返回 None),否则继续构造子树。

       后序的遍历结果决定了我们只能先创建右子树再创建左子树(先序+中序差异之处),借助 “栈” 数据结构将后序中根节点依次弹出该方法的核心就是用后序序列元素即根节点分割中序序列

代码实现如下:

	public TreeNode buildTree(int[] inorder, int[] postorder) {
	    if(inorder ==null || postorder ==null){
			return null;
		}
		List<Integer> inorderList =  new ArrayList<>();
		Stack<Integer> postorderStack = new Stack<>();
		for(int i=0;i< inorder.length;i++){
			inorderList.add(inorder[i]);
			postorderStack.push(postorder[i]);		
		}
		return bulidTree(inorderList,postorderStack);
	}

    private TreeNode bulidTree(List<Integer> inorder,Stack<Integer> postorder){
		if(inorder.isEmpty() || postorder.isEmpty()){
			return null;
		}
		
		int val =  postorder.pop();
		int index = inorder.indexOf(val);
		if(index < 0){
			return null;
		}
		
		List<Integer> left = inorder.subList(0,index);
		List<Integer> right = inorder.subList(index + 1,inorder.size());
		TreeNode curNode = new TreeNode(val);
		curNode.right= bulidTree(right,postorder);//先创建右子树
		curNode.left= bulidTree(left,postorder);
		
		return curNode;
    
    }

3、LeetCode297. 二叉树的序列化与反序列化

 

4、小结

        无论是先序+中序 还是 中序+ 后序 构建唯一二叉树的原理都是用根节点将中序序列分割成左右两个子树。需要说明的是 先序和后序在本质上都是将父节点与子结点进行分离,但并没有指明左子树和右子树的能力,因此得到这两个序列只能明确父子关系,而不能确定一个唯一的二叉树。记住下面这个简单的例子。

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老王不让用

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值