首页 > 编程语言 >【Java】/* 二叉树 - 底层实现*/

【Java】/* 二叉树 - 底层实现*/

时间:2024-08-26 20:56:31浏览次数:7  
标签:Java 打印 二叉树 left return null root 节点 底层

一、前序遍历 - 递归

/* 1. 前序遍历 - 递归 */
    public void preOrder(TreeNode root) {
        //1. 如果根节点为null
        if (root == null) {
            return;
        }

        //本意:打印树的根,左,右节点

        //2. 打印根节点的值
        System.out.print(root.val + " ");
        //3. 如果root.left也有左,右节点...,
        //   我们直接使用sout打印root.left.val...会造成打印不全。
        //   既然子树也是树,那么我们可以利用方法的递归去处理
        preOrder(root.left);
        preOrder(root.right);
    }

二、中序遍历 - 递归

/* 2. 中序遍历 - 递归 */
    public void inOrder(TreeNode root) {
        //1. 如果根节点为null
        if (root == null) {
            return;
        }

        //本意:打印树的左,根,右节点

        //2. 如果root的左树也是一颗完整的树,
        //   此时直接打印root.left会造成打印不完全的现象
        //   既然如此,我们可以利用递归先打印root.left再打印当前树的根节点
        inOrder(root.left);
        //3. 打印根节点的值
        System.out.print(root.val + " ");
        //4. 打印root右树
        preOrder(root.right);
    }

 

三、后续遍历 - 递归

/* 3. 后续遍历 - 递归 */
    public void postOrder(TreeNode root) {
        //1. 如果根节点为null
        if (root == null) {
            return;
        }

        //本意:打印树的左,右,根节点

        //2. 如果root的左树也是一颗完整的树,
        //   此时直接打印root.left会造成打印不完全的现象
        //   既然如此,我们可以利用递归先打印root.left再打印当前树的右树和根节点
        postOrder(root.left);
        postOrder(root.right);
        //3. 打印根节点的值
        System.out.print(root.val + " ");
    }

【小结】:

1. 之所以用到递归是由于root的左树,右树也是一颗完整的树,想要打印完整得先采用递归打印root的左树,右树,而不是直接用sout打印root.left,root.right。

2. 通过画图分析可知,当发现一个节点A的left节点为null时,会返回,使得代码回退到节点A的栈帧中,继续执行后面的打印节点A的right节点的代码。

四、其他方法

package bagone;

import javax.management.relation.InvalidRoleInfoException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: tangyuxiu
 * Date: 2024-08-26
 * Time: 18:43
 */
public class MyBinaryTree {
    /* 使用内部类来表示树的节点 */
    private static class TreeNode {
        char val;
        TreeNode left;
        TreeNode right;

        public TreeNode(char val) {
            this.val = val;
        }
    }

    /* 1. 前序遍历 - 递归 */
    public void preOrder(TreeNode root) {
        //1. 如果根节点为null
        if (root == null) {
            return;
        }

        //本意:打印树的根,左,右节点

        //2. 打印根节点的值
        System.out.print(root.val + " ");
        //3. 如果root.left也有左,右节点...,
        //   我们直接使用sout打印root.left.val...会造成打印不全。
        //   既然子树也是树,那么我们可以利用方法的递归去处理
        preOrder(root.left);
        preOrder(root.right);
    }

    /* 2. 中序遍历 - 递归 */
    public void inOrder(TreeNode root) {
        //1. 如果根节点为null
        if (root == null) {
            return;
        }

        //本意:打印树的左,根,右节点

        //2. 如果root的左树也是一颗完整的树,
        //   此时直接打印root.left会造成打印不完全的现象
        //   既然如此,我们可以利用递归先打印root.left再打印当前树的根节点
        inOrder(root.left);
        //3. 打印根节点的值
        System.out.print(root.val + " ");
        //4. 打印root右树
        preOrder(root.right);
    }

    /* 3. 后续遍历 - 递归 */
    public void postOrder(TreeNode root) {
        //1. 如果根节点为null
        if (root == null) {
            return;
        }

        //本意:打印树的左,右,根节点

        //2. 如果root的左树也是一颗完整的树,
        //   此时直接打印root.left会造成打印不完全的现象
        //   既然如此,我们可以利用递归先打印root.left再打印当前树的右树和根节点
        postOrder(root.left);
        postOrder(root.right);
        //3. 打印根节点的值
        System.out.print(root.val + " ");
    }

    /* 4. 树的节点个数 - 子问题思路 */
    public int size(TreeNode root) {
        //1. 如果根节点为null
        if (root == null) {
            return 0;
        }

        //2. 根节点1 + 左树节点个数 + 右树节点数
        return 1 + size(root.left) + size(root.right);
    }

    /* 4. 树的节点个数 - 遍历思路 */
    public int sizeTreeNode;
    public void sizeTwo(TreeNode root) {
        //1. 如果根节点为null
        if (root == null) {
            return;
        }

        //本质:遍历树的根,左,右如果不为空sizeTreeNode的值就++

        //2. 根节点算一个所以++
        sizeTreeNode++;

        //3. root的左树,右树节点个数
        //   这里不可能直接下成判断不为null后sizeTreeNode的值就++
        //   因为root的左,右节点也是一颗树,下列代码中不接收返回值,
        //   或着说size方法的返回值为什么要定义成void是因为,我们已经定义了成员变量去记录成员个数了
        //   不用多此一举
        size(root.left);
        size(root.right);
    }

    /* 5. 获取叶子节点的个数 - 子问题思路 */
    public int getLeafNodeCount(TreeNode root) {
        //1. 如果根节点为null
        if (root == null) {
            return 0;
        }

        //2. 如果根节点的左右子树都为null
        if (root.left == null && root.right == null) {
            return 1;
        }

        //3. 收集左树,右树的叶子节点个数
        return getLeafNodeCount(root.left) + getLeafNodeCount(root.right);
    }

    /* 5. 获取叶子节点的个数 - 遍历思路 */
    public int sizeLeafNode;
    public void getLeafNodeCountTwo(TreeNode root) {
        //1. 如果根节点为null
        if (root == null) {
            return;
        }

        //2. 如果根节点的左右子树都为null
        if (root.left == null && root.right == null) {
            sizeLeafNode++;
        }

        //3. 收集左树,右树的叶子节点个数
        getLeafNodeCount(root.left);
        getLeafNodeCount(root.right);
    }

    /* 6. 获取第K层节点的个数 */
    public int getKLevelNodeCount(TreeNode root, int k) {
        //条件:所给的k一定是合法的
        //1. 如果根节点为null(递归的过程中也会出现root为null的情况)
        if (root == null) {
            return 0;
        }

        //2. k == 1
        if (k == 1) {
            return 1;
        }

        //3. 求root的左树,右树的第k-1层
        return getKLevelNodeCount(root.left, k - 1) + getKLevelNodeCount(root.right, k - 1);
    }

    /* 7. 获取二叉树的高度 */
    public int getHeight(TreeNode root) {
        //1. 如果根节点为null
        if (root == null) {
            return 0;
        }

        // 核心:一棵树的高度等于,左树右树相比较的高度max + 1

        int hightOne = getHeight(root.left);
        int hightTwo = getHeight(root.right);
        return Math.max(hightOne,hightTwo) + 1;
    }

    /* 8. 检测值为value的元素是否存在 */
    public TreeNode find(TreeNode root, char val) {
        //1. 如果根节点为null
        if (root == null) {
            return root;
        }

        //2. 判断根节点的值是否为val
        if (root.val == val) {
            return root;
        }

        //3. root的左树,右树,是否存在val值
        TreeNode valNode = find(root.left, val);
        if (valNode != null) {
            return valNode;
        }

        valNode = find(root.right, val);
        //4. 不管是否为null,直接返回valNode中的值即可
        return valNode;
    }
}

标签:Java,打印,二叉树,left,return,null,root,节点,底层
From: https://blog.csdn.net/YX54201/article/details/141571419

相关文章

  • 【数据结构篇】~链式二叉树(附源码)
    链式二叉树前言(含头文件)头文件1.链式二叉树的组成2.前、中、后、层序遍历1.前序遍历2.中序遍历3.后序遍历3.结点个数以及高度等​4.判断二叉树是否为完全二叉树前言(含头文件)之前的堆是特殊的二叉树是顺序结构的二叉树,而链式二叉树使用队列实现的。二叉树的实现大......
  • Java中的异常
    目录一、异常的概念二、异常的分类1.编译时异常2.运行时异常3.错误(Error)三、异常的处理方式1.使用try-catch语句捕获异常: 2.使用try-catch-finally语句: 3.使用throws关键字声明方法可能抛出的异常:四、自定义异常一、异常的概念在Java中,异常是在程序运行过程中......
  • 新Java萝卜影视4.0.5原生源码【完美修复完整版】
    新Java萝卜影视4.0.5原生源码【完美修复完整版】新Java萝卜影视4.0.5原生源码【完美修复完整版】源码介绍新Java萝卜影视4.0.5是一个基于Java语言开发的影视播放应用。该版本在原有基础上进行了多项优化和修复,提升了应用的稳定性和用户体验。源码采用原生Java编写,适合Java开......
  • 基于Java+SpringBoot+Mysql实现高校教务信息系统功能设计与实现二
    一、前言介绍:1.1项目摘要高校教务信息系统课题的提出,主要源于高校日常管理工作的复杂性和重要性。作为高校的基本任务,人才培养离不开教学与管理工作的有效组织和协调。教务管理作为高校日常管理的核心组成部分,涉及教学资源的合理配置、教学过程的科学规划以及教学质量的......
  • 基于Java+SpringBoot+Mysql实现高校教务信息系统功能设计与实现三
    一、前言介绍:1.1项目摘要高校教务信息系统课题的提出,主要源于高校日常管理工作的复杂性和重要性。作为高校的基本任务,人才培养离不开教学与管理工作的有效组织和协调。教务管理作为高校日常管理的核心组成部分,涉及教学资源的合理配置、教学过程的科学规划以及教学质量的......
  • 计算机毕业设计-基于Java+SSM架构的高校毕业生就业管理系统项目开发实战(附源码+论文)
    大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。......
  • java在项目中实现个性化定制的数据可视化图表———静态,动态获取数据
    一、Echarts介绍ECharts是一款基于JavaScript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。ECharts最初由百度团队开源,并于2018年初捐赠给Apache基金会,成为ASF孵化级项目。2021年1月26日晚,Apache基金会官方宣布ECharts项目正式毕业。1月28日,EChar......
  • 如何构建KPL比赛在线售票系统——Java SpringBoot与Vue的完美结合
    ......
  • Java 入门指南:初识 Java IO
    JavaIOJavaIO(Input/Output)是Java编程语言中用于处理输入和输出的标准库,它提供了一组类和接口,用于在程序和外部世界(如文件、网络连接、内存等)之间进行数据传输。IO,即in和out,也就是输入和输出,即应用程序和外部设备之间的数据传递,常见的外部设备包括文件、管道、网络......
  • Java将数据导出为Excel文件
    使用ApachePOI生成基本ExcelApachePOI是一个强大的Java库,用来处理MicrosoftOffice文件。对于Excel文件(.xls和.xlsx)处理,提供有HSSF(.xls)和XSSF(.xlsx)等API。importorg.apache.poi.ss.usermodel.*;importorg.apache.poi.xssf.usermodel.XSSFWorkbook;importjavax.serv......