日撸java 三百行 (day 11 )二叉树及其基本操作

今天开启新篇章,进入树这一数据结构,主要是递归操作。

二叉树作为树的代表,是一种常用的数据结构,其所有节点的度最多为2。

  • 二叉树的三种遍历

先序遍历:、左、右

中序遍历:左、、右

后序遍历:左、右、

记忆技巧:左右位置相对不变,根的位置与之遍历名字相对应。

先序遍历是在 递 的过程中输出节点,中序与后序则是在 归 的过程中输出节点

二叉树求高度与求节点数则是在 归 过程中通过相应的计数操作得到

先序遍历图(中、后同理):

 

 

package com.day11;

/**
 * 存储char类型元素的二叉树.
 */
public class day11_BinaryCharTree {

    /**
     * The value in char.
     */
    char value;
    /**
     * The left child.
     */
    day11_BinaryCharTree left;
    /**
     * The right child
     */
    day11_BinaryCharTree right;

    /**
     * ********************
     * 构造方法.
     *
     * @param value The value.
     *              ********************
     */
    public day11_BinaryCharTree(char value) {
        this.value = value;
        left = null;
        right = null;
    }//of day11_BinaryCharTree

    /**
     * ********************
     * 静态方法构造出一个用于测试的二叉树
     * ********************
     */
    public static day11_BinaryCharTree manualConstructTree() {
        day11_BinaryCharTree tempA = new day11_BinaryCharTree('a');
        day11_BinaryCharTree tempB = new day11_BinaryCharTree('b');
        day11_BinaryCharTree tempC = new day11_BinaryCharTree('c');
        day11_BinaryCharTree tempD = new day11_BinaryCharTree('d');
        day11_BinaryCharTree tempE = new day11_BinaryCharTree('e');
        day11_BinaryCharTree tempF = new day11_BinaryCharTree('f');
        day11_BinaryCharTree tempG = new day11_BinaryCharTree('g');

        tempA.left = tempB;
        tempA.right = tempC;
        tempC.left = tempE;
        tempB.right = tempD;
        tempD.left = tempF;
        tempD.right = tempG;

        return tempA;
    }//of manualConstructTree

    /**
     * ********************
     * 先序遍历.
     * ********************
     */
    public void preOrderVisit() {
        System.out.print("" + value + " ");
        if (left != null) {
            left.preOrderVisit();
        }//of if
        if (right != null) {
            right.preOrderVisit();
        }//of if
    }//of preOderVisit


    /**
     * ********************
     * 中序遍历.
     * ********************
     */
    public void inOrderVisit() {
        if (left != null) {
            left.inOrderVisit();
        } // Of if

        System.out.print("" + value + " ");

        if (right != null) {
            right.inOrderVisit();
        } // Of if
    }// Of inOrderVisit

    /**
     * ********************
     * 后序遍历.
     * ********************
     */
    public void postOrderVisit() {
        if (left != null) {
            left.postOrderVisit();
        } // Of if

        if (right != null) {
            right.postOrderVisit();
        } // Of if

        System.out.print("" + value + " ");
    }// Of postOrderVisit

    /**
     * ********************
     * 求二叉树的深度
     *
     * @return 深度值.
     * ********************
     */
    public int getDepth() {
        int leftdeep = 0;
        int rightdeep = 0;
        if (left != null) {
            leftdeep = left.getDepth();
        }//of if
        if (right != null) {
            rightdeep = right.getDepth();
        }//of if
        return leftdeep > rightdeep ? leftdeep + 1 : rightdeep + 1;
    }//of getDepth

    /**
     * ********************
     * 求二叉树的节点数.
     *
     * @return 节点数.
     * ********************
     */
    public int getNumNodes() {
        // It is a leaf.
        if ((left == null) && (right == null)) {
            return 1;
        } // Of if

        // The number of nodes of the left child.
        int tempLeftNodes = 0;
        if (left != null) {
            tempLeftNodes = left.getNumNodes();
        } // Of if

        // The number of nodes of the right child.
        int tempRightNodes = 0;
        if (right != null) {
            tempRightNodes = right.getNumNodes();
        } // Of if

        // The total number of nodes.
        return tempLeftNodes + tempRightNodes + 1;
    }// Of getNumNodes

    /**
     * ********************
     * 程序入口.
     *
     * @param args 暂未使用.
     *             ********************
     */
    public static void main(String args[]) {
        day11_BinaryCharTree tempTree = manualConstructTree();
        System.out.println("\r\n先序遍历:");
        tempTree.preOrderVisit();
        System.out.println("\r\n中序遍历:");
        tempTree.inOrderVisit();
        System.out.println("\r\n后序遍历:");
        tempTree.postOrderVisit();

        System.out.println("\r\n\r\n高度: " + tempTree.getDepth());
        System.out.println("节点数: " + tempTree.getNumNodes());
    }// Of main


}//of day11_BinaryCharTree


运行结果:

总结:递归的代码依然简洁,也是一如既往的烧脑细胞,求高度的代码在递的过程中不做操作,在归的过程中就相当厉害了

 在归的过程从叶子节点开始,反着推上去,每个节点都取左右孩子里最大值并加一

求总结点数的代码与求高度本质上我感觉没有啥区别,都是归的过程中“计数”,我自己写的时候尝试在递去过程中直接计数,不过后来发现有问题。

在类里设置静态变量 nodes,在递去的过程中直接修改nodes来计数,但是随后发现在递归的方法中没办法维护这个nodes,还需要单独写个方法来reset nodes,不然就是一次性计数。

定义静态变量作为计数器

递去过程中修改nodes,最后直接返回nodes 

 

 手动维护nodes

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值