• 二叉树的遍历与重建 Gentleman


    1、二叉树的遍历

         是指从二叉树的根结点出发,按照某种次序依次访问二叉树中的所有结点,使得每个结点被访问一次,且仅被访问一次。
    二叉树的访问次序可以分为四种:

    前序遍历
    中序遍历
    后序遍历
    层序遍历

    1.1、前序遍历通俗的说就是从二叉树的根结点出发,当第一次到达结点时就输出结点数据,按照先向左在向右的方向访问。

     上图所示二叉树访问如下:

      
    从根结点出发,则第一次到达结点A,故输出A;
    继续向左访问,第一次访问结点B,故输出B;
    按照同样规则,输出D,输出H;
    当到达叶子结点H,返回到D,此时已经是第二次到达D,故不在输出D,进而向D右子树访问,D右子树不为空,则访问至I,第一次到达I,则输出I;
    I为叶子结点,则返回到D,D左右子树已经访问完毕,则返回到B,进而到B右子树,第一次到达E,故输出E;
    向E左子树,故输出J;
    按照同样的访问规则,继续输出C、F、G;
    
    作者:MrHorse1992
    链接:https://www.jianshu.com/p/bf73c8d50dc2
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    则上图所示二叉树的前序遍历输出为: ABDHIEJCFG
          

    1.2、中序遍历就是从二叉树的根结点出发,当第二次到达结点时就输出结点数据,按照先向左在向右的方向访问。

    上图所示二叉树中序访问如下:

    从根结点出发,则第一次到达结点A,不输出A,继续向左访问,第一次访问结点B,不输出B;继续到达D,H;
    到达H,H左子树为空,则返回到H,此时第二次访问H,故输出H;
    H右子树为空,则返回至D,此时第二次到达D,故输出D;
    由D返回至B,第二次到达B,故输出B;
    按照同样规则继续访问,输出J、E、A、F、C、G;

    则上图所示二叉树的中序遍历输出为:HDIBJEAFCG

    1.3、后序遍历就是从二叉树的根结点出发,当第三次到达结点时就输出结点数据,按照先向左在向右的方向访问。

    上图所示二叉树后序访问如下:

    从根结点出发,则第一次到达结点A,不输出A,继续向左访问,第一次访问结点B,不输出B;继续到达D,H;
    到达H,H左子树为空,则返回到H,此时第二次访问H,不输出H;
    H右子树为空,则返回至H,此时第三次到达H,故输出H;
    由H返回至D,第二次到达D,不输出D;
    继续访问至I,I左右子树均为空,故第三次访问I时,输出I;
    返回至D,此时第三次到达D,故输出D;
    按照同样规则继续访问,输出J、E、B、F、G、C,A;

    则上图所示二叉树的后序遍历输出为:HIDJEBFGCA

    当然前中后三种遍历方式,也可以简单的理解为:

    前序就是 父节点->左子树->右子树,

    中序是 左子树->父节点->右子树,

    后序是 左子树 -> 右子树 ->父节点

    递归在其中非常重要,每棵子树又可以重新遍历,依此类推,遍历完成。

    1.4、层次遍历

    层次遍历就是按照树的层次自上而下的遍历二叉树。针对上图所示二叉树的层次遍历结果为:ABCDEFGHIJ

    2、二叉树重建

    二叉树的重建,只能在提供前序+中序,或者后序+中序的情况下,才可以正常的重构。

      • 前序+中序:
        1、前序遍历数组中的第一个数就是根节点,得到根节点的数字。
        2、然后在中序遍历中找到该根节点的位置,中序数组的左边就是该根节点的左子树,中序遍历的右边序列是其右子树。
        3、前序遍历中根据中序遍历中根节点的位置,将前序遍历分为前序遍历的左子树和右子树。
        4、根节点就确定了,最后将前序和中序划分出来的左右子树,分别带入递归得到左右子树的构建情况。
      • 后序+中序
        1.后续遍历的最后一个节点是根节点,然后中序遍历中找出根节点位置mid。
        2.再在根据中序遍历中的mid位置将后序遍历数组和中序遍历数据分为左子树和右子树。
        3.最后将划分完成的左右子树递归。

    Java代码实现如下:

    public class RebuildBinaryTree {
        //假设输入的前序遍历和中序遍历的结果中都不含重复的数字
        /*
          前序遍历第一位是根节点;
          中序遍历中,根节点左边的是根节点的左子树,右边是根节点的右子树。
          例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}。
          首先,根节点 是{ 1 };
          左子树是:前序{ 2,4,7 } ,中序{ 4,7,2 };
          右子树是:前序{ 3,5,6,8 } ,中序{ 5,3,8,6 };
          这时,如果我们把左子树和右子树分别作为新的二叉树,则可以求出其根节点,左子树和右子树。
         */
    /*
    pre 前序序列数组
    in 中序序列数组
    */
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) { if(pre==null||in==null){ return null; } TreeNode treeNode=reConstructBinaryTree(pre, in,0,pre.length-1,0,in.length-1); return treeNode; }

         /*
    pre 前序序列数组
    in 中序序列数组
    preStart 前序序列第一个节点的索引值
    preEnd 前序序列最后一个节点的索引值
    inStart 中序序列第一个节点的索引值
    inEnd 中序序列最后一个节点的索引值
         */
    public TreeNode reConstructBinaryTree(int [] pre,int [] in,int preStart,int preEnd,int inStart,int inEnd) {
             TreeNode tree=new TreeNode(pre[preStart]);  //前序遍历的第一个是根节点,递归时把左子树和右子树分别作为新的二叉树
             tree.left=null;
             tree.right=null;
             if(preStart==preEnd&&inStart==inEnd){   //说明已经是树叶节点
                 return tree;
             }
             int root;
             for(root=inStart;root<inEnd;root++){       //寻找根节点在中序遍历中的下标
                 if(pre[preStart]==in[root]){
                     break;
                 }
             }
             int leftLength=root-inStart;       //左子树的长度
             int rightLength=inEnd-root;        //右子树的长度
             //把左子树和右子树分别作为新的二叉树,则可以求出其根节点,左子树和右子树。
             if(leftLength>0){
                 tree.left=reConstructBinaryTree(pre,in,preStart+1,preStart+leftLength,inStart,root-1);
             }
             if(rightLength>0){
                 tree.right=reConstructBinaryTree(pre,in,preStart+1+leftLength,preEnd,root+1,inEnd);
             }
             return  tree;
        }
    }
    不忘初心,相信自己,坚持下去,付诸实施。
  • 相关阅读:
    ArcGIS Server 服务迁移、恢复
    发布(高程数据)服务,Service Editor界面无LERC格式选项
    汇总10.4版本ArcGIS Server与ArcMap 安装+SDE+注册数据源(非破解)
    ArcGIS Server 缓存服务增加新比例尺缓存
    ArcMap 标注、注记、图形文本
    ArcGIS Server 缓存服务切图范围
    Oracle 安装 INS-30131错误。
    JAVA经典算法40题(供面试所用)
    Java 之HashMap.values()方法误用
    Java中如何把两个数组合并为一个
  • 原文地址:https://www.cnblogs.com/controller666/p/14445314.html
Copyright © 2020-2023  润新知