zoukankan      html  css  js  c++  java
  • 2、二叉树:递归遍历

      

    对二叉树而言,最为核心的操作就是遍历。遍历可以用递归的方式,也可以用循环的方式。

    就递归遍历而言,又有“先序、中序、后续”三种不同的遍历顺序。通过下面的一个示意图可以从感官上来体会一下三种不同的遍历顺序:

    为了学习二叉树的相关算法,首先需要构建一个二叉树的抽象类public abstract class BiTreeAbstract<T> ,该类中有一个表示结点的内部类Node,将结点的数据类型定义为泛型T以方便将其用于不同的数据类型。

      1 package com.magicode.datastructure.tree;
      2 
      3 public abstract class BiTreeAbstract<T> {
      4     /**
      5      * 树的根节点。
      6      */
      7     private Node root;
      8 
      9     /**
     10      * 具体的构建二叉树方法。 如果构建成功,则返回二叉树的根节点(Node); 如果构建失败,则范湖null。
     11      * 
     12      * @return 二叉树的根节点Node
     13      */
     14     abstract protected Node initMethod();
     15 
     16     /**
     17      * 访问二叉树中的元素节点。 如果需要终止遍历,则返回false;如果需要继续遍历下去,则返回true。
     18      * 
     19      * @return
     20      */
     21     abstract protected boolean visitElem(Node node);
     22 
     23     /**
     24      * 创建一个二叉树,在此方法中具体调用抽象方法initMethod来 创建一个二叉树。
     25      * 
     26      * @return
     27      */
     28     public boolean createBiTree() {
     29         root = initMethod();
     30         if (root != null) {
     31             return true;
     32         }
     33         return false;
     34     };
     35 
     36     /**
     37      * 递归的“先序”遍历二叉树</br> 具体会调用抽象方法visitElem来具体处理遍历过程中的元素。
     38      * 
     39      * @return 遍历成功,则返回true。遍历失败,返回false。
     40      */
     41     public boolean preOrderTraverse() {
     42         return preTraverse(root);
     43     }
     44 
     45     private boolean preTraverse(Node node) {
     46         if (node == null) {
     47             return true;
     48         }
     49         // 改变下面三条if语句的先后关系,就可以实现“中序”和“后序”递归遍历
     50         if (visitElem(node))
     51             if (preTraverse(node.lchild))
     52                 if (preTraverse(node.rchild))
     53                     return true;
     54         return false;
     55     }
     56 
     57     public Node getRoot() {
     58         return root;
     59     }
     60 
     61     /**
     62      * 节点结构
     63      */
     64     protected class Node {
     65 
     66         private T elem;
     67         private Node lchild;
     68         private Node rchild;
     69 
     70         public Node() {
     71         }
     72 
     73         public Node(T elem) {
     74             this.elem = elem;
     75             lchild = null;
     76             rchild = null;
     77         }
     78 
     79         public T getElem() {
     80             return elem;
     81         }
     82 
     83         public Node getLchild() {
     84             return lchild;
     85         }
     86 
     87         public Node getRchild() {
     88             return rchild;
     89         }
     90 
     91         public void setElem(T elem) {
     92             this.elem = elem;
     93         }
     94 
     95         public void setLchild(Node lchild) {
     96             this.lchild = lchild;
     97         }
     98 
     99         public void setRchild(Node rchild) {
    100             this.rchild = rchild;
    101         }
    102 
    103     }
    104 
    105 }
    BiTreeAbstract抽象类

    抽象类中定义了两个功能方法:

    ①、public boolean createBiTree()用于构建一个二叉树,在该方法中会调用abstract protected Node initMethod()方法来具体的对构建二叉树; 

    ②、public boolean preOrderTraverse()方法的功能是先序递归的方法来遍历二叉树,它会调用抽象方法abstract protected boolean visitElem(Node node)在遍历过程对访问的当前节点进行处理,如果想在某个结点处终止遍历,只需要在visitElem方法中返回一个false即可。

    下面是一个具体的实现类,它会构建一个满二叉树:

     1 package com.magicode.datastructure.tree;
     2 
     3 public class BiTree extends BiTreeAbstract<Integer> {
     4 
     5     private int n = 0;
     6     private String[] dat = "1|2|3|4|0|0|5|0|0|6|7|0|0|8|0|0|9|10|11|0|0|12|0|0|13|14|0|0|15|0|0".split("\|");
     7     
     8     private Node create(String[] str) {
     9         Integer ele = Integer.parseInt(str[n]);
    10         n++;
    11         //0表示该孩子节点为null
    12         if(ele == 0){
    13             return null;
    14         }
    15         Node nod = new Node(ele);
    16         //先构建左孩子,后构建右孩子。构建顺序于先序遍历是一致的。
    17         nod.setLchild(create(str));
    18         nod.setRchild(create(str));
    19         return nod;
    20     }
    21 
    22     @Override
    23     protected Node initMethod() {
    24         Node nd = create(dat);
    25         return nd;
    26     }
    27 
    28     @Override
    29     protected boolean visitElem(Node node) {
    30         System.out.print(node.getElem() + " ");
    31         return true;
    32     }
    33     
    34     public static void main(String[] args) {
    35         BiTree tree = new BiTree();
    36         System.out.println(tree.createBiTree());
    37         
    38         System.out.println();
    39         System.out.println("--------先序遍历------");
    40         tree.preOrderTraverse();
    41         
    42     }
    43 
    44 }
    public class BiTree extends BiTreeAbstract

    运行测试结果(中序和后序只需要依据代码说明进行修改即可实现):

  • 相关阅读:
    使用shell数据处理数据实例①-------手把手教学版
    python requests模块中返回时间elapsed解析
    一个简单web系统的接口性能分析及调优过程
    mock server搭建及接口测试简单实例
    linux下jmeter持续集成Jenkins部署时问题解决
    jmeter函数助手之time函数实操
    jmeter聚合报告导出时乱码的解决
    C++ Windows API 读写INI文件
    VC++运行库 集32位/64位整合版
    Installshield2015 定制安装在C:Program files 目录 不正确问题
  • 原文地址:https://www.cnblogs.com/lj95801/p/5243087.html
Copyright © 2011-2022 走看看