zoukankan      html  css  js  c++  java
  • java代码实现二叉树的遍历

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://blog.csdn.net/qq_33275597/article/details/52759223
    一、二叉树的定义:

    二叉树是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树的形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。
        二叉树(BinaryTree)是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的、分别称作这个根的左子树和右子树的二叉树组成。
        这个定义是递归的。由于左、右子树也是二叉树, 因此子树也可为空树。下图中展现了五种不同基本形态的二叉树。

    其中 (a) 为空树, (b) 为仅有一个结点的二叉树, (c) 是仅有左子树而右子树为空的二叉树, (d) 是仅有右子树而左子树为空的二叉树, (e) 是左、右子树均非空的二叉树。这里应特别注意的是,二叉树的左子树和右子树是严格区分并且不能随意颠倒的,图 (c) 与图 (d) 就是两棵不同的二叉树。


    二、二叉树的遍历:
    对于二叉树来讲最主要、最基本的运算是遍历。
        遍历二叉树 是指以一定的次序访问二叉树中的每个结点。所谓 访问结点 是指对结点进行各种操作的简称。例如,查询结点数据域的内容,或输出它的值,或找出结点位置,或是执行对结点的其他操作。遍历二叉树的过程实质是把二叉树的结点进行线性排列的过程。假设遍历二叉树时访问结点的操作就是输出结点数据域的值,那么遍历的结果得到一个线性序列。

    常见的遍历方法:

    1、先序遍历法:先访问根节点,再遍历左子树,最后遍历右子树;

    2、中序遍历法:先遍历左子树,再访问根节点,最后遍历右子树;

    3、后序遍历法:先遍历左子树,再遍历右子树,最后访问根节点。

    三、话不多说,上代码。

    public class BinaryTree {

    /**
    * BinaryTree 的节点数据结构
    */
    private class TreeNode{
    private int key = 0;
    private String data = null;
    private boolean isVisited = false;
    private TreeNode leftChild = null;
    private TreeNode rightChild = null;

    public TreeNode(){}
    public TreeNode(int key,String data){
    this.key = key;
    this.data = data;
    this.leftChild = null;
    this.rightChild = null;
    }
    }

    //获取根节点
    public TreeNode getRoot() {
    return root;
    }

    public void setRoot(TreeNode root) {
    this.root = root;
    }


    //定义根节点
    private TreeNode root = null;
    public BinaryTree(){
    root = new TreeNode(1,"A");
    }

    /**
    * 创建一棵二叉树
    */
    public void createBinaryTree(TreeNode root){
    TreeNode nodeB = new TreeNode(2,"B");
    TreeNode nodeC = new TreeNode(3,"C");
    TreeNode nodeD = new TreeNode(4,"D");
    TreeNode nodeE = new TreeNode(5,"E");
    TreeNode nodeF = new TreeNode(6,"F");
    root.leftChild = nodeB;
    root.rightChild = nodeC;
    nodeB.leftChild = nodeD;
    nodeB.rightChild = nodeE;
    nodeC.rightChild = nodeF;

    }

    /**
    * 前序遍历
    */
    public void preOrder(TreeNode node){
    if(node != null){
    visited(node);
    preOrder(node.leftChild);
    preOrder(node.rightChild);
    }
    }
    /**
    * 中序遍历
    * @param node
    */

    public void inOrder(TreeNode node){
    if(node != null){
    preOrder(node.leftChild);
    visited(node);
    preOrder(node.rightChild);
    }
    }
    /**
    * 后序遍历
    * @param node
    */

    public void postOrder(TreeNode node){
    if(node != null){
    preOrder(node.leftChild);
    preOrder(node.rightChild);
    visited(node);
    }
    }
    /**
    * 非递归前序遍历
    * @param node
    */

    public void nonRecPreOrder(TreeNode node){
    Stack<TreeNode> stack = new Stack<>();
    TreeNode pNode = node;
    while(pNode != null || stack.size()>0){
    while(pNode != null){
    visited(pNode);
    stack.push(pNode);
    pNode = pNode.leftChild;
    }
    if(stack.size()>0){
    pNode = stack.pop();
    pNode = pNode.rightChild;
    }
    }
    }
    /**
    * 非递归中序遍历
    * @param node
    */

    public void nonRecInOrder(TreeNode node){
    Stack<TreeNode> stack = new Stack<>();
    TreeNode pNode = node;
    while(pNode != null || stack.size()>0){
    while(pNode != null){
    stack.push(pNode);
    pNode = pNode.leftChild;
    }
    if(stack.size()>0){
    pNode = stack.pop();
    visited(pNode);
    pNode = pNode.rightChild;
    }
    }
    }

    /**
    * 非递归后序遍历
    * @param pNode
    */
    public void nonRecPostOrder(TreeNode pNode){
    Stack<TreeNode> stack = new Stack<>();
    TreeNode node = pNode;
    while(pNode != null){
    //左子树入栈
    while(pNode.leftChild != null){
    stack.push(pNode);
    pNode = pNode.leftChild;
    }
    //当前节点无右子树或者右子树已输出
    while(pNode != null && (pNode.rightChild == null || pNode.rightChild == node)){
    visited(pNode);
    //记录上一个已输出的节点
    node = pNode;
    if(!stack.isEmpty()){
    pNode = stack.pop();
    }else{
    return;
    }
    }
    //右子树入栈
    stack.push(pNode);
    pNode = pNode.rightChild;
    }
    }

    private void visited(TreeNode node) {
    node.isVisited = true;
    System.out.println(node.data+","+node.key);
    }

    /**
    * 计算树的高度
    */
    private int height(TreeNode node){
    if(node == null){
    return 0;
    }else{
    int i = height(node.leftChild);
    int j = height(node.rightChild);
    return (i<j)?j+1:i+1;
    }
    }

    /**
    * 计算树的节点数
    * @param node
    * @return 树的节点数
    */

    private int size(TreeNode node){
    if(node == null){
    return 0;
    }else{
    return 1+size(node.leftChild)+size(node.rightChild);
    }
    }



    public static void main(String[] args) {
    BinaryTree binaryTree = new BinaryTree();
    TreeNode root = binaryTree.root;
    binaryTree.createBinaryTree(root);
    System.out.println(binaryTree.height(root));
    System.out.println(binaryTree.size(root));
    binaryTree.preOrder(root);
    System.out.println("*******");
    binaryTree.nonRecPreOrder(root);
    System.out.println("*******");
    binaryTree.nonRecInOrder(root);
    System.out.println("-------------");
    binaryTree.nonRecPostOrder(root);
    }

    }
    输出结果:
    3
    6
    A,1
    B,2
    D,4
    E,5
    C,3
    F,6
    *******
    A,1
    B,2
    D,4
    E,5
    C,3
    F,6
    *******
    D,4
    B,2
    E,5
    A,1
    C,3
    F,6
    -------------
    D,4
    E,5
    B,2
    F,6
    C,3
    A,1

    ————————————————
    版权声明:本文为CSDN博主「专注移动开发技术」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_33275597/article/details/52759223

  • 相关阅读:
    cookie与session的原理及区别
    jwt原则
    Django rest framework基础 RESTful风格
    vue项目使用整理
    Serializer 字段验证以及序列化
    ModelSerializer 字段验证以及序列化
    Django
    FREE 命令结果完全剖析
    一个一元二次方程求解编程引申的两个知识点(abs和fabs的区别以及浮点数比较相等)
    signed和unsigned之二
  • 原文地址:https://www.cnblogs.com/yunleijava/p/11545574.html
Copyright © 2011-2022 走看看