颠沛流离学二叉树(完结撒花篇)

本篇会加入个人的所谓鱼式疯言

❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言

而是理解过并总结出来通俗易懂的大白话,

小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.

🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 !!!

在这里插入图片描述

前言

在上两篇 二叉树系列 的文章中,我们学习了二叉树的 概念特性遍历方式 , 而在本篇文章中,将展开对 二叉树其他基本核心操作 的详解 ❤️ ❤️ ❤️ ❤️

提前透露一下哦, 本篇文章的基本操作,小编都会带着大家用 递归非递归 的代码带着大家走一遍哦 💖 💖 💖 💖

目录

  1. 获取树中节点的个数

  2. 获取叶子节点的个数

  3. 获取第 K 层的节点的个数

  4. 获取二叉树的高度(最大深度)

  5. 查找 节点的值等于的 value 的节点

  6. 判断一棵树是否是完全二叉树

一. 获取树中节点的个数

1. 操作分析

由于我们的二叉树是分为 两边的,分别是 左子树右子树 , 要求树中的节点,我们就需要知道 左子树的节点右子树的节点 ,最后加上自身的 1个根节点

在这里插入图片描述

2. 代码实现

<1>. 递归实现

// 递归计算节点个数
public int Size(TreeNode root) {if (root==null) {return 0;}return Size(root.left)+1+Size(root.right);
}

递归的代码实现,就是咱们 动画上的执行过程 了,小编在这里就不赘述了 💞 💞 💞 💞

动画展示

请添加图片描述

在这里插入图片描述

<2>. 非递归实现

// 非递归遍历节点个数public int nodeSize;public void setNodeSize(TreeNode root) {if (root==null) {return;}// 只要遍历过的节点// 就让 节点数 ++nodeSize++;// 先遍历左子树setNodeSize(root.left);// 遍历右子树setNodeSize(root.right);}

在这里插入图片描述

非递归的执行过程 :

我们这里利用了 前序遍历 的思路, 当我们每走过一个节点,就让我们的 nodeSize++

当完全的走过 每一个节点 , 我们 的 nodeSize 就加多少次

当我们遍历完 整个二叉树 , 也就统计出二叉树 所有的节点

鱼式疯言

关于求树中接节点个数的操作,小编最大的体会就是 子问题递归思路

由于我们 递归 的是不断把 每一个节点重新看成是根节点 的思路

所以我们只需要求出每个根节点的个数。所累积的个数,不就是我们的 节点总数 吗 ! ! !

这就是 子问题 的思路, 小伙伴在思考这一类问题时,一定要学会把一个 大问题 拆分成我们能解决的 一个一个小问题 的思想.

二. 获取叶子节点的个数

1. 操作分析

小伙伴都知道我们 二叉树的叶子节点 的定义,就是 度为0 的节点

那么我们该怎么找 度为零 的节点呢 💞 💞 💞 💞

其实很简单,我们只需要返回 左右子树所有节点 同时 左节点右子树 也为 null

最后 左右子树的叶子节点相加 即可

在这里插入图片描述

2. 代码实现

<1>. 递归实现

// 递归计算叶子个数
public int leafSize(TreeNode root) {if (root==null) {return 0;}if (root.left==null && root.right==null) {return 1;}return leafSize(root.left)+leafSize(root.right);
}

在这里插入图片描述

关于 递归实现 的执行步骤,下面就让小编用 动画 的形式来描述吧 😊 😊 😊 😊

动画展示

请添加图片描述

<2>. 非递归实现

public int leafSize;// 非递归求叶子节点的个数public void setLeafSize(TreeNode root) {if (root==null) {return;}// 如果左右节点为 null// 就是我们需要的节点if (root.right==null && root.left==null) {leafSize++;}// 遍历左子树setLeafSize(root.left);// 遍历右子树setLeafSize(root.right);}

在这里插入图片描述

非递归的实现过程

非递归的根本是依赖于 我们的遍历 来实现的,当遍历到某个 左节点为 null 并且 右节点也为 null 时, 就令 leafSize ++

当遍历完整个 二叉树的所有节点,也就意味着 所有的叶子节点 已经被 leafSize 统计完了

鱼式疯言

对于 递归实现 的思路来说,我们还是用 子问题 的思路,把一棵树拆成 多颗子树

子树 又成为 新的树, 在新的树里面去寻找 左右子树都为null 的节点 ,

最终回归到 最开始的整棵树 上解决该问题 ! ! !

三. 获取第 K 层的节点的个数

1. 操作分析

要得到 第 K 层的节点 , 不免想起我们上一篇文章中所用的 层序遍历 的思想, 每一层也就相当于 二维数组中的每一行

所有要得到 每一层的节点数 ,本质上就是当我们 递归往下递的每走一行的 左子树和右子树 , k 就 减去一行 。

最终 当 K = 1 时, 就回退到 整棵树的根节点 ,就是我们要 获取到 第 K 层的节点个数

在这里插入图片描述

2. 代码实现

 // 求树某深度的节点数public int treeIndexlength(TreeNode root , int key) {// 如果节点为 null 返回 0if (root==null) {return 0;}/**** 当 k = 1 时 就意味着到底最后一层* 返回当前根节点即可****/// 如果 这个位置 没有左右if (key==1) {return 1;}/*** 先统计左边的节点** 再统计右边的节点** 最后都要减少 key 次* 代表统计了一层** 也就是说每统计一层 ,就减少一层**///int left = treeIndexlength(root.left,key-1);// 再统计右边的节点int right = treeIndexlength(root.right,key-1);// 一直返回该 key 位置的节点return left+right;}

在这里插入图片描述

具体 递归的过程 我们通过下面动画展示:请添加图片描述

鱼式疯言

扩展一下

小伙伴有没有想到一个点:

   // 一直返回该 key 位置的节点return left+right;

我们这边是 直接返回 left + right 是得到我们当前 第k层 深度的节点数

但如果我们

 return left+right + 1;  

我们如果是 + 1 呢?

答案就是返回 从整棵树的根节点第k层所有节点总和

感兴趣的小伙伴可以自己 研究 哦, 小编在这里就不细讲了 💖 💖 💖 💖**(代码如下)**

// 求树某深度的到根节点所有节点数
public int treeIndexSize(TreeNode root , int key) {if (root==null) {return 0;}if (key==1) {return 1;}int left=treeIndexSize(root.left,key-1);int right=treeIndexSize(root.right,key-1);// key 位置开始查找节点 并 一直累加return left+right+1;
}

四.获取树的高度(最大深度)

1. 操作分析

要获取高度小伙伴们先得理解高度该怎么来, 我们可以设想一下,

如果一颗树的左子树高度为 3 右子树的高度为 4 , 那么 这颗树的高度是 3 还是 4

很显然 这都 不对

树的高度最终应该是 5 才对, 因为啊, 我们树的高度是 左右子树中较高的那个高度 再 + 上自身根节点的高度 1 , 所以我们得到的树的高度是 4 + 1 才对

在这里插入图片描述

2. 代码实现

// 返回树的最大深度
public int treeHeight(TreeNode root) {if (root==null) {return 0;}// 求左子树的深度int leftnum=treeHeight(root.left);// 求右子树的深度int rightnum=treeHeight(root.right);/*** 根据左右子树两边的高度** 哪边高 取 哪边*  最后还要加上该节点的高度**/return leftnum>rightnum? leftnum+1: rightnum+1;
}

在这里插入图片描述

具体我们由于递归不好描述,请小伙伴们看动画分析递归的全过程哦 💫 💫 💫 💫

动画展示

请添加图片描述

鱼式疯言

当我们用 子问题 的思路 在 寻找数的高度 的关键在于我们要注意加上不仅要比较 两端左子树右子树高度, 那个自身的 根节点的 1 也要同时加上

五. 查找节点的值等于的 value 的节点

1. 操作分析

查找某个等于 val 的值, 我们就需要在 遍历的基础上 完成

所以我们只需要考虑 一点 即可,当我们在遍历过程

如果 左子树或者右子树 的节点的 val 找到了等于 val 就返回该 节点 , 如果没找到就返回 null .

在这里插入图片描述

2. 代码实现

// 查找节点public TreeNode find(TreeNode root, char val) {if(root==null) {return null;}// 判断新的根节点的 val 是否 等于目标值 valif (Character.compare(val,root.val)==0) {return  root;}// 在左子树中查找该节点TreeNode node1=  find(root.left,val);// 一旦找到就返回该节点if (node1 !=null) {return node1;}// 在右子树中查找该今节点TreeNode node2= find(root.right,val);// 一点找到就返回该节点if (node2 !=null) {return node2;}// 都没有找到就返回 nullreturn  null;}

在这里插入图片描述

下面我们看看动画对于这段代码的理解吧 🤔 🤔 🤔 🤔

动画展示

请添加图片描述

鱼式疯言

细节处理:

   // 在左子树中查找该节点TreeNode node1=  find(root.left,val);// 一旦找到就返回该节点if (node1 !=null) {return node1;}// 在右子树中查找该今节点TreeNode node2= find(root.right,val);// 一点找到就返回该节点if (node2 !=null) {return node2;}

我想肯定有小伙伴会直接返回 node1 或者 node2 的值, 而不加判断, 这样做是不是有点问题呢 ???

是的,是有些问题,小伙伴应该知道如果我们先 递归左子树 或者 右子树 来达到遍历的效果, 一但 左子树没有找到该 val目标值 ,就会去右边的 右子树

p但我们 中途一旦返回,就会陷入只找寻 左边一个节点 ,然后就直接返回了,未达到遍历的效果 , 也就更不可能找到我们的 val 值了

六. 判断一棵树是否是完全二叉树

1. 操作分析

要考虑是否是完全二叉树,我们只需要考虑一点即可:

左子树 < 右子树高度 : 用 -1 来标记,代表 不是完全二叉树

左子树 >= 右子树高度: 就返回该高度

在这里插入图片描述

2. 代码实现

/*** 检查左子树和右子树的高度关系* * 当左子树 > 右子树时 ,就不是完全二叉树* 否则就是完全二叉树* @param root 根节点* @return 返回布尔类型* */private int CheckTreeCount(TreeNode root) {if (root==null) {return  0;}int left=CheckTreeCount(root.left);/*** 当此树不是完全二叉树的就返回 负数* * 而这里的判断是为了连接上一个递归下来的根节点* */// 当左子树不是完全二叉树时,就返回 -1 if (left < 0) {return -1;}int right=CheckTreeCount(root.right);// 当右子树不是完全二叉树时, 就返回 -1 if(right < 0) {return  -1;}// 当左子树的高度 < 右子树的高度// 就说明不是完全二叉树if (left < right) {return -1;} else {// 该节点是完全二叉树时,就返回当前高度return Math.max(left,right)+1;}}

在这里插入图片描述

具体实现,请小伙伴们观看下面动态理解哦 ❣️ ❣️ ❣️ ❣️

请添加图片描述

鱼式疯言

int left=CheckTreeCount(root.left);/*** 当此树不是完全二叉树的就返回 负数* * 而这里的判断是为了连接上一个递归下来的根节点* */// 当左子树不是完全二叉树时,就返回 -1 if (left < 0) {return -1;}int right=CheckTreeCount(root.right);// 当右子树不是完全二叉树时, 就返回 -1 if(right < 0) {return  -1;}

细节处理

这里有小伙伴就问了,我可以把

   if (left < 0) {return -1;}

if(right < 0) {return  -1;}

去掉吗?

答案是 不行

因为当我们一旦判断出 有一颗子树 的 左子树的高度 > 右子树的高度 时 , 就必须返回 -1 ,然后就必须回退到上一个 根节点

如果没有及时返回 -1 ,就有可能造成 max(-1,-1) 的情况,这种情况是 不可预料 的,所以我们呢需要 及时返回

总结

  1. 获取树中节点的个数: 我们通过都用了 子问题遍历 的获取节点的个数,但子问题要 注意的是需要加上自身的那个 节点数的 1

  2. 获取叶子节点的个数 : 获取叶子节点,我们主要是根据它自身的特点 (左右节点是否同时为 null ) ,成立时我们就返回 当前节点 .

  3. 获取第 K 层的节点的个数 : 获取 第K层的节点数 的思路在遍历的情况下,每走一层,k就减去1 , 当 k= 1 时就到达该层,返回 该层节点数 即可

  4. 获取二叉树的高度(最大深度):求树的高度,本质是抓住我们左子树和右子树的 较高 的那个高度,然后 加上 自身的高度1 即可

  5. 查找 节点的值等于的 value 的节点 :查找 val 是在遍历的情况下完成的,只需要在 边遍历边查找一旦找到就返回该节点即可

  6. 判断一棵树是否是完全二叉树 : 完全二叉树的判断是建立在获取二叉树高度的思路上进行变通的, 根据完全二叉树成立条件: 左子树 >= 右子树 ,这个特点来判断即可

如果觉得小编写的还不错的咱可支持 三连 下 (定有回访哦) , 不妥当的咱请评论区 指正

希望我的文章能给各位宝子们带来哪怕一点点的收获就是 小编创作 的最大 动力 💖 💖 💖

在这里插入图片描述

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

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

相关文章

MT2083 屠龙勇者

思路&#xff1a; 跟上题类似&#xff0c;贪心策略&#xff1a;w从小到大排序&#xff0c;每个头找到第一个>d的w 代码&#xff1a; #include <bits/stdc.h> using namespace std; #define ll long long const int N 1e5 10; int n, m; int d[N]; int w[N]; int …

Spring Security 注册过滤器关键点与最佳实践

在 Spring Security 框架中&#xff0c;注册过滤器是实现身份验证和授权的关键组件。正确配置和使用注册过滤器对于确保应用程序的安全性至关重要。以下是一些关于 Spring Security 注册过滤器的注意事项和最佳实践。 过滤器链顺序&#xff1a; 注册过滤器通常位于过滤器链的末…

[next.js]pwa缓存

配置Next.js (v14 App Router模式) 使其支持PWA缓存&#xff0c;配置server worker和mainfest.json&#xff0c;让项目支持离线访问和可安装。 安装依赖next-pwa npm i next-pwa配置next.config.js const path require(path);const withPWAInit require(next-pwa);// 判断…

想要成长就要持续地学习,而如何学习更有效率呢

为什么很多人学了知识&#xff0c;但是总感觉记不住&#xff0c;用不上呢&#xff1f; 在学习的过程中&#xff0c;为什么总感觉没什么进步呢&#xff1f; 看了很多书&#xff0c;为什么总感觉没什么用呢&#xff1f; 要说明这些问题&#xff0c;首先我们要知道一个好的、完整的…

Chrome跳转新的标签页自动打开控制台设置方法

Chrome跳转新的标签页自动打开控制台设置方法 文章目录 Chrome跳转新的标签页自动打开控制台设置方法1. 首先打开控制台2. 点击设置3. 选择Preferences -> Global -> 选中 Auto-open DevTools for popups4. 回到控制台勾选 preserve log保留日志![请添加图片描述](https:…

图像背景去除工具:removebg

文章目录 简介面向不同用户价格 简介 removebg&#xff0c;就是remove background&#xff0c;是一款智能图片背景去除工具。 在免费使用时&#xff0c;用到的是本地的CPU。我第一次试用时&#xff0c;图片刚上传之后&#xff0c;电脑的帧率便直线下降&#xff0c;鼠标都拖不…

硬件26、EDA绘制板框

1、放置-板框-矩形 2、在pcb上绘制出需要大小的板框 3、设置板框四个角为圆弧状&#xff0c;在右侧属性栏设置圆角半径

计算机网络—交换机综合实验

一、实验内容 交换机基本配置设置虚拟局域网VLAN跨交换机实现VLAN2台交换机间用2条链路连接&#xff0c;实现2条链路聚合 二、实验环境 Cisco Packet Tracer 三、实验拓扑 1、 设置虚拟局域网VLAN 2、跨交换机实现VLAN 3、2台交换机间用2条链路连接&#xff0c;实现2条链…

像图一样交流:为大语言模型编码图

译者 | 高永祺 单位 | 东北大学自然语言处理实验室 原文链接&#xff1a;https://blog.research.google/2024/03/talk-like-graph-encoding-graphs-for.html 1.作者介绍 Bahare Fatemi&#xff0c;谷歌蒙特利尔研究部门的研究科学家&#xff0c;专门从事图表示学习和自然语言…

智能推荐算法应用:如何提升淘宝在线扭蛋机用户购物体验

在淘宝的在线扭蛋机平台上&#xff0c;用户的购物体验至关重要。为了提升这一体验&#xff0c;我们引入了智能推荐算法&#xff0c;帮助用户发现他们可能感兴趣的扭蛋产品。这一技术的应用不仅提高了用户的购物效率&#xff0c;还大大增强了用户的购物乐趣。 一、智能推荐算法…

做抖音小店卖什么最赚钱?精准锁定爆款的技巧!新手商家必看

哈喽~我是电商月月 做抖音小店的核心就是选品&#xff0c;商品好&#xff0c;出单的几率就多&#xff0c;那么怎么选中一个好的商品&#xff0c;就是每个商家必须细琢的一个技巧&#xff01; 为了解答这个疑惑&#xff0c;今天月月就给大家介绍几个赚钱的类别&#xff0c;并教…

semaphore | 使用web界面的ansible来批量运维 linux、windows主机

Ansible 的现代化 UI &#xff0c;可以轻松管理和运行 Ansible playbook&#xff0c;功能强大&#xff0c;操作简单&#xff0c;支持中文。 文章目录 一、系统功能说明二、系统安装2.1 直接安装2.2 docker 安装 三、系统使用3.1 建立存储库3.2 编写代码3.3 建立主机配置3.3 建立…

南卡、韶音、Cleer、漫步者开放式耳机好用吗?最强开放式耳机对比揭秘!

在挑选开放式耳机时&#xff0c;个人经验和实际需求应当优先考虑&#xff0c;而非盲目追随潮流或品牌效应。投资耳机前务必慎重&#xff0c;毕竟高价值商品若无法退换&#xff0c;难免造成遗憾。为了帮助大家做出更加明智的决策&#xff0c;我亲自出资购买并测试了市面上多款主…

重生奇迹mu魔剑士

1、魔剑士低端装备-SF10(升级)亚特传说等S-S(PK)亚特奔雷魔神等。评价:优越的极品双属卓越,极其高的性价比,造福穷人玩家的装。 2、中端装备(只适合力魔剑士)-SF10S-S天魔斗神评价&#xff1a;与低级亚特等一样不过由于成本,装备PVP属性等原因,价钱稍贵点。 3、中端套装(只适合…

【阿里前端面试题】聊聊前端性能优化的方案,解决过什么样的性能问题?

大家好&#xff0c;我是“寻找DX3906”。每天进步一点。日积月累&#xff0c;有朝一日定会厚积薄发&#xff01; 前言&#xff1a; 前面已经和大家分享了4篇面试题&#xff1a; 《【阿里前端面试题】浏览器的加载渲染过程》 《【阿里前端面试题】客户端和服务器交互&#xff…

IO流----字节流

字节流 字节流&#xff1a;操作&#xff1a;文件字节输入输出流 &#xff1a;写入数据&#xff1a;读取数据&#xff1a;文件拷贝&#xff1a; 带缓冲区的字节输入输出流&#xff1a;拷贝文件&#xff1a;写入数据&#xff1a;读取数据: 深入 带缓冲区的字节输出流 &#xff1a…

【论文阅读】Point2RBox (CVPR’2024)

paper:https://arxiv.org/abs/2311.14758 code:https://github.com/yuyi1005/point2rbox-mmrotate

阿里云sls 采集日志安装记录

参考阿里云给的安装文档 阿里云安装Logtail组件 注意这里&#xff0c;选择地域&#xff0c;是中国地域选中国&#xff0c;海外选海外即可 按照文档继续下去 修改配置文件./alibaba-cloud-log-all/values.yaml 所有的操作完成后&#xff0c;去控制台配置 以上操作的前提是…

[WWW2024]轻量数据依赖的异常检测重训练方法LARA

开篇 近日&#xff0c;由阿里云计算平台大数据基础工程技术团队主导&#xff0c;与浙江大学合作的论文《LARA: ALight and Anti-overfitting Retraining Approach for Unsupervised Time Series Anomaly Detection 》被WWW2024收录&#xff0c;该方法解决了云服务正常模式随时…

探索AIGC降重工具:确保论文原创性的新策略

如何有效降低AIGC论文的重复率&#xff0c;也就是我们说的aigc如何降重&#xff1f;AIGC疑似度过高确实是个比较愁人的问题。如果你用AI帮忙写了论文&#xff0c;就一定要在交稿之前做一下AIGC降重的检查。一般来说&#xff0c;如果论文的AIGC超过30%&#xff0c;很可能会被判定…