数据结构之初始二叉树(2)

找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程(ಥ_ಥ)-CSDN博客

所属专栏:数据结构(Java版)

二叉树的前置知识(概念、性质、、遍历)

通过上篇文章的学习,我们已经知道什么是二叉树,以及其性质和遍历的方式了。接下来主要是实现代码。

目录

伪创建二叉树

遍历二叉树 

获取二叉树中节点的个数 

获取二叉树中叶子节点的个数

获取二叉树中第K层节点的个数

获取二叉树的高度 

在二叉树中找寻元素 


伪创建二叉树

为啥叫伪创建二叉树呢?因为我们现在才刚开始学习二叉树,而创建二叉树是一个非常复杂的过程(树的递归定义的)。因此我们就先手动的来创建二叉树。树是有一个一个的结点组成,因此得先把结点创建出来。树的结点我们采用的是简单的孩子表示法:

    // 树的结点static class TreeNode {public char val; // 数据域public TreeNode left; // 左子树public TreeNode right; // 右子树public TreeNode(char val) {this.val = val;}}

创建的二叉树图形如下:

    public TreeNode createBinaryTree() {TreeNode A = new TreeNode('A');TreeNode B = new TreeNode('B');TreeNode C = new TreeNode('C');TreeNode D = new TreeNode('D');TreeNode E = new TreeNode('E');TreeNode F = new TreeNode('F');TreeNode G = new TreeNode('G');// 根据图形关系把结点之间相连A.left = B;A.right = C;B.left = D;B.right = E;C.left = F;C.right = G;// 返回根结点return A;}

遍历二叉树 

二叉树创建完成后,我们就可以遍历打印二叉树,看看是否符合我们的预期结果。遍历的四种方式,我们前面也学习了。

前序遍历: 

    // 前序遍历public void preOrder(TreeNode root) {if (root == null) {return;}// 打印根结点的值System.out.print(root.val+" ");// 递归遍历根的左子树preOrder(root.left);// 递归遍历根的右子树preOrder(root.right);}

递归的限制条件:当递归到 root 为 null 时,就开始回退。随着递归的深入,root 不断的接近 null。

中序遍历:

    // 中序遍历public void inOrder(TreeNode root) {// 中序遍历:左子树->根->右子树if (root == null) {return;}// 递归遍历根的左子树inOrder(root.left);// 打印根结点的值System.out.print(root.val+" ");// 递归遍历根的右子树inOrder(root.right);}

后序遍历:

    // 后序遍历public void postOrder(TreeNode root) {// 后序遍历:左子树->右子树->根if (root == null) {return;}// 递归遍历根的左子树postOrder(root.left);// 递归遍历根的右子树postOrder(root.right);// 打印根结点的值System.out.print(root.val+" ");}

由于层序遍历还是比较复杂,因此我们后面再学习。

获取二叉树中节点的个数 

思路一:这个同样是遍历二叉树,遇到不为空的结点就++,最后统计的就是树的节点个数。

    // 记录节点个数public int treeNodeSize; public void size(TreeNode root) {if (root == null) {return;}// 根结点treeNodeSize++;// 左子树size2(root.left);// 右子树size2(root.right);}

思路二:整棵树的节点个数等于 根结点+左子树的节点个数+右子树的节点个数

    // 获取树中节点的个数public int size(TreeNode root) {if (root == null) {return 0;}// 左子树的节点个数+右子树的节点个数+根结点return size(root.left)+size(root.right)+1;}

思路一采用的是遍历的方式,思路二采用的是化为子问题的方式。思路二也是更加接近递归的方式。

获取二叉树中叶子节点的个数

思路:首先,我们得知道什么是叶子节点。叶子结点的特点是其左孩子和右孩子都是null。同样这也是采用遍历的方式。

法一:采用子问题思路

    // 获取叶子节点的个数public int getLeafNodeCount(TreeNode root) {if (root == null) {return 0;}// 遇到叶子结点就返回1if (root.left == null && root.right == null) {return 1;}// 返回左子树的叶子节点个数+右子树的叶子节点个数return getLeafNodeCount(root.left) + getLeafNodeCount(root.right);}

法二:采用遍历思路

    public int leafSize;public void getLeafNodeCount(TreeNode root) {if (root == null) {return;}if (root.left == null && root.right == null) {leafSize++;}// 遍历左子谁getLeafNodeCount2(root.left);// 遍历右子树getLeafNodeCount2(root.right);}

获取二叉树中第K层节点的个数

上面是对于第K层的介绍,根结点是作为第一层。 

思路:当K为1时,就可以直接返回这一层的节点个数即可。因此我们就是要递归到K不断的接近1.

法一: 采用子问题思路

    // 获取第K层节点的个数public int getKLevelNodeCount(TreeNode root, int k) {// 假定不存在K无效的情况if (root == null) {return 0;}if (k == 1) {return 1;}// 左子树的第k-1层的节点个数+右子树的第k-1层的节点个数return getKLevelNodeCount(root.left, k-1) +getKLevelNodeCount(root.right, k-1);}

法二: 采用遍历思路

    public int getLevelNodeSize;public void getKLevelNodeCount(TreeNode root, int k) {// 假定不存在K无效的情况if (root == null) {return;}if (k == 1) {getLevelNodeSize++;}// 遍历左子树的第k-1层getKLevelNodeCount2(root.left, k-1);// 遍历右子树的第k-1层getKLevelNodeCount2(root.right, k-1);}

获取二叉树的高度 

思路:获取二叉树的高度和求第K层节点的个数类似。同样根结点算高度为1。接着就是分别递归计算左子树和右子树的高度的最大值。

采用子问题思路

    // 获取二叉树的高度public int getHeight(TreeNode root) {if (root == null) {return 0;}// 左子树与右子树的最大高度+根结点return Math.max(getHeight(root.left), getHeight(root.right)) + 1;}

这个如果不采用子问题思路,而是用遍历思路的话,只能用层序遍历来写,又因为层序遍历过于复杂,因此我们暂时先不写这个代码。

在二叉树中找寻元素 

 思路:这个比较简单,就是遍历去比较即可。

    // 检测值为value的元素是否存在public TreeNode find(TreeNode root, int val) {if (root == null) {return null;}// 采用前序遍历的方式:根->左子树->右子树// 根if (root.val == val) {return root;}// 在左子树中寻找,肯定有一个结果TreeNode findLeft = find(root.left, val);// 如果不为null,则说明找到了if (findLeft != null) {return findLeft;}// 在右子树中寻找,肯定有一个结果,不管结果如何直接返回即可return find(root.right, val);}

注意:这里在寻找二叉树中的节点时,采用前序遍历的方式是最有效率的。因为前序遍历是首先比较根结点,而我们就是需要比较根结点。 

对于二叉树的基本操作我们就已经学习完了。基于上述基本操作就可以进行一些简单的刷题了,后续也会在刷题中继续完善二叉树的相关操作。

好啦!本期 数据结构之初始二叉树(2)的学习之旅就到此结束啦!我们下一期再一起学习吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/46475.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TCP/IP中的复用、分解和封装

TCP/IP(传输控制协议/互联网协议)模型中,复用(Multiplexing)、分解(Demultiplexing)和封装(Encapsulation)是关键概念,它们帮助管理和传输数据在网络上的有效…

【Linux】centos7安装PHP7.4报错:libzip版本过低

问题描述 configure: error: Package requirements (libzip > 0.11 libzip ! 1.3.1 libzip ! 1.7.0) were not met: checking for libzip > 0.11 libzip ! 1.3.1 libzip ! 1.7.0... no configure: error: Package requirements (libzip > 0.11 libzip ! 1.3.1 libzi…

Java中线程启动:start()与run()方法的区别

Java中线程启动:start()与run()方法的区别 1. start()方法2. run()方法3、总结4、示例对比 💖The Begin💖点点关注,收藏不迷路💖 线程是并发执行的基本单位,而…

中科亿海微亮相慕尼黑上海电子展

7月8-10日,备受瞩目的全球电子行业盛会“慕尼黑上海电子展”以空前规模启幕,汇聚了超过1600家参展企业,涵盖了从终端产品制造商到元器件供应商、组装/系统供应商、EMS、ODM/OEM、材料供应商及生产设备供应商的完整产业链。中科亿海微电子科技…

《昇思25天学习打卡营第22天|基于MindSpore的GPT2文本摘要》

#学习打卡第22天# 1. 数据集 1.1 数据下载 使用nlpcc2017摘要数据,内容为新闻正文及其摘要,总计50000个样本。 from mindnlp.utils import http_get from mindspore.dataset import TextFileDataset# download dataset url https://download.mindspor…

活用 localStorage

我维护的这款工具 https://editor.yunwow.cn/ 已经帮我写了 7 篇文章了, 用起来很顺手,因此我打算再给它升级下让它更方便,我决定要给它加个本地缓存功能。我给它提的要求是: 1. 至少能缓存 5 篇文章 2. 能有选择的加载模板 3…

MySQL-对数据库和表的DDL命令

文章目录 一、什么是DDL操作二、数据库编码集和数据库校验集三、使用步骤对数据库的增删查改1.创建数据库2.进入数据库3.显示数据库4.修改数据库mysqldump 5.删除数据库 对表的增删查改1.添加/创建表2.插入表内容3.查看表查看所有表查看表结构查看表内容 4.修改表修改表的名字修…

融云:换头像=换人设?社交应用中隐秘而重要的「用户信息管理」

当代年轻人失眠三大原因,最近新上的《喜人奇妙夜》帮你找到了—— 基金绿了、吵架输了、前任头像换了。 当你半夜翻看前任的社交账号,一场盛大的失眠就开始了,就算古希腊掌柜睡眠的神躺你旁边也不好使。即便 Ta 没有更新内容,昵…

Redis 中String类型操作命令(命令演示,时间复杂度,返回值,注意事项)

String 类型 文章目录 String 类型set 命令get 命令mset 命令mget 命令get 和 mget 的区别incr 命令incrby 命令decr 命令decrby 命令incrbyfloat 命令append 命令getrange 命令setrange 命令 字符串类型是 Redis 中最基础的数据类型,在讲解命令之前,我们…

Linux的load(负载)

负载(load)是Linux机器的一个重要指标,直观了反应了机器当前的状态。 在Linux系统中,系统负载是对当前CPU工作量的度量,被定义为特定时间间隔内运行队列中的平均线程数。 Linux的负载高,主要是由于CPU使用、内存使用、10消…

新款S32K3 MCU可解决汽车软件开发的成本和复杂性问题(器件编号包含S32K322E、S32K322N、S32K328)

全新的S32K3系列专门用于车身电子系统、电池管理和新兴的域控制器,利用涵盖网络安全、功能安全和底层驱动程序的增强型封装持续简化软件开发。 相关产品:S32K328NHT1VPCSR S32K328GHT1MPCSR S32K322NHT0VPASR S32K322EHT0VPBSR S32K322NHT0VPBSR S32K32…

Doris数据库---建表、调整表结构操作

一、简介 本文章主讲创建 Doris 自维护的表的语法,以下为本人最近为数据中台接入doris所踩的坑及其解决方案,欢迎点评。 二、doris建表语法: 官网建表语法网址链接:CREATE-TABLE - Apache Doris 官网建表语法如图所示&#xf…

【C++】构造函数详解

📢博客主页:https://blog.csdn.net/2301_779549673 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! 📢本文由 JohnKi 原创,首发于 CSDN🙉 📢未来很长&#…

windows服务器搭建区块链环境(node.js+truffle+ganache)

windows服务器搭建区块链环境(node.jstruffleganache) 1,安装node.js中文版的2,更改下载源3,安装truffle4,安装ganache(可以跳过使用ganache-cli)5,安装ganache-cli&…

starRocks搭建

公司要使用新的大数据架构,打算用国产代替国外的大数据平台。所以这里我就纠结用doris还是starrocks,如果用doris,因为是开源的,以后就可以直接用云厂商的。如果用starrocks就得自己搭建,但是以后肯定会商业化&#xf…

医院护士站卫星电子钟,时间精准,为众人提供精确的时间引导

在医院这个充满紧张与关怀的环境中,每一刻的时间都承载着生命的重量。医院护士站卫星电子钟以其精准的时间显示,成为了为众人提供精确时间引导的重要存在。 一、医院卫星电子钟应用原因 首先,护士站是医院内信息交流和医疗服务协调的核心区域…

Springboot自定义banner启动动画

一、banner文件自定义编写 1、创建banner文件 banner文件的文件名称默认为“banner.txt”,这个在SpringApplication.java中定义的 一般自定义就新建一个banner.txt文件,放在项目resources中。这时在banner.txt中编写启动动画展示内容。例如: banner.t…

【排序算法】—— 归并排序

归并排序时间复杂度O(NlongN),空间复杂度O(N),是一种稳定的排序,其次可以用来做外排序算法,即对磁盘(文件)上的数据进行排序。 目录 一、有序数组排序 二、排序思路 三、递归实现 四、非递归实现 一、有序数组排序 要理解归…

mysql(5.5)启动服务和环境配置

正常启动 参考:Javaweb基础之mysql回溯笔记(一) 总的来说就是在mysql的安装目录下,找到bin下面的msyqld.exe,双击即启动了mysql服务; 启动方式二 也可以直接找到windows的服务项进行启动,操作如下: 打开…

Mac电脑下运行java命令行出现:错误: 找不到或无法加载主类

mac 电脑 问题复现 随手写了一个main方法,想用命令行操作 进入 BlockDemo.java 所在目录: wnwangnandeMBP wn % cd /Users/wn/IdeaProjects/test/JianZhiOffer/src/main/java/com/io/wn wnwangnandeMBP wn % ls -l total 16 -rw-r--r-- 1 wangnan …