zoukankan      html  css  js  c++  java
  • 【算法】重建二叉树(前+中、后+中)

    (一)二叉树的重建

      二叉树是非线性结构,每个结点会有零个、一个或两个孩子结点,一个二叉树的遍历序列不能决定一棵二叉树,但某些不同的遍历序列组合可以惟一确定一棵二叉树。

      可以证明,给定一棵二叉树的前序遍历序列和中序遍历序列可以惟一确定一棵二叉树的结构,给定一棵二叉树的后序遍历序列和中序遍历序列也可以惟一确定一棵二叉树的结构。

      注意:这还有一个条件:二叉树的任意两个结点的值都不相同

      算法如下:

    1. 用前序序列的第一个结点(后序序列的最后一个结点)作为根结点;

    2. 在中序序列中查找根结点的位置,并以此为界将中序序列划分为左、右两个序列(左、右子树);

    3. 根据左、右子树的中序序列中的结点个数,将前序序列(后序)去掉根结点后的序列划分为左、右两个序列,它们分别是左、右子树的前序(后序)序列;

    4. 对左、右子树的前序(后序)序列和中序序列递归地实施同样方法,直到所得左、右子树为空。

    (二)根据前序和中序序列确定二叉树

      参考题目:

      【剑指Offer】4、重建二叉树

      LeetCode105、Construct Binary Tree from Preorder and Inorder Traversal

    class Solution {
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder==null || inorder==null)
                return null;
            return buildTree(preorder,inorder,0,preorder.length-1,0,inorder.length-1);
        }
        public TreeNode buildTree(int[] preorder,int[]inorder,int pStart,int pend,int iStart,int iend){
            if(pStart>pend || iStart>iend)
                return null;
            TreeNode root=new TreeNode(preorder[pStart]);  //前序序列第一个为根
            if(pStart==pend)
                return root;
            int mid=iStart;
            while(mid<=iend && inorder[mid]!=root.val)
                mid++;
            //找到mid即为根在中序序列中的位置
            int leftCount=mid-iStart;
            //重建左子树和右子树
            root.left=buildTree(preorder,inorder,pStart+1,pStart+leftCount,iStart,mid-1);
            root.right=buildTree(preorder,inorder,pStart+leftCount+1,pend,mid+1,iend);
            return root;
        }
    }
    

    (三)根据后序和中序序列确定二叉树

      参考题目:

      LeetCode106、Construct Binary Tree from Inorder and Postorder Traversal

    class Solution {
        public TreeNode buildTree(int[] inorder, int[] postorder) {
            if(inorder==null || postorder==null)
                return null;
            return buildTree(inorder,postorder,0,inorder.length-1,0,postorder.length-1);
        }
        public TreeNode buildTree(int[] inorder,int[] postorder,int iStart,int iend,int pStart,int pend){
            if(iStart>iend || pStart>pend)
                return null;
            //后续遍历序列的最后一个为根
            TreeNode root=new TreeNode(postorder[pend]);
            if(pStart==pend)
                return root;
            int mid=iStart;
            while(mid<=iend && inorder[mid]!=root.val)
                mid++;
            int leftCount=mid-iStart;
            root.left=buildTree(inorder,postorder,iStart,mid-1,pStart,pStart+leftCount-1);
            root.right=buildTree(inorder,postorder,mid+1,iend,pStart+leftCount,pend-1);
            return root;
        }
    }
    
  • 相关阅读:
    用C++实现从键盘输入两个数a和b,求两数中的最大值
    MongoDB学习笔记-1
    linux 配置ip地址
    linux 配置jdk 环境变量
    VMware Linux 共享文件夹 虚拟机无共享文件解决方法
    数据库动态参数
    js
    js分页
    mysql存储过程
    webconfig 中配置上传文件大小
  • 原文地址:https://www.cnblogs.com/gzshan/p/11185529.html
Copyright © 2011-2022 走看看