刷题记录(7)二叉树

一、单值二叉树

二叉树为二叉链表形式,结点为:

大概看看题就知道这道题让我们判断一个树到底所有结点的值是不是相同,相同就是单值二叉树。在实现二叉树相关操作的时候已经体会到了,递归来遍历二叉树是非常舒服的(做这些题本质都得遍历)。

所以我们考虑考虑递归怎么个递归法,而二叉树递归其实就是考虑根结点以及左右子树之间的关系。

容易想到判断根结点与左右孩子结点是否结点,当然,由于需要访问左右孩子结点,根结点不能为空,而且因为访问的是三个结点的值,所以肯定三个结点都得先保证不为空。

这个就有点讲究了,根结点不能为空,假设刚好遍历到一个空结点,空结点的值实际上并不是二叉树实际上的值,对二叉树是不是单值二叉树不影响,所以碰见为空返回值需要不影响判断结果。

接下来就是分别判断左右子树是不是也符合了,这个逻辑就简单了,因为直接上递归就行,新的根结点分别是root->left和root->right,其它就没了。

代码表达:

只不过最后的递归直接省成一个布尔表达式了,因为能走到最后一个retrun语句至少说明根结点和它的左右孩子符合单值二叉树,如果左右子树同时符合单值二叉树,那肯定就是单值二叉树,但凡出现不符合的情况,我们给出来的语句都可以判断,且有&&,一个不符合最后都是false。

测试通过:

提交通过:

二、相同的树

给你一个树,你得给我判断出来到底是相同还是不同的,什么是相同的树呢,结构和数值完全一样的树就是相同的树。比如典例2,典型的数值一样,但是同样的根结点,左边的树,左孩子为2,右孩子为空;典例3这俩树不看数值其实是完全一样的,但是孩子结点的数值并不是一一对应的。

其实说来还是遍历,只不过是同步遍历,也就是这样:

如果同步遍历完了还没有检测出不一样的结点,显然就是相同的树,否则就是不同的树。

还是立足根结点写出代码,再用递归去判断左右子树的情况。

因为要判断值,所以肯定保证根不为空,因为两个根,所以就有三种情况了:

都为空,一个为空(显然不是相同树,因为同步遍历),都不为空。

只不过需要注意的是第二个条件的写法,全空已经排除过了,那至少有一个为非空,此时就剩下一个空一个非空和全非空,如果再有空岂不是就是一个空一个非空了嘛,直接return false就行,其它都简单。

三、对称二叉树

这道题其实基本不用做了,因为如果相同二叉树做出来了,那么对称二叉树很明显就是每次遍历的结点刚好走的路径相反而已:

分类基本是模仿相同树来的,当然,return啥肯定得对着典例写。

比较容易弄错的就是最后递归按镜像走路,不过对着典例写就行。

四、另一棵树的子树

其实这个题在我们做过判断二叉树是否相同以后就简单了,遍历整棵树,如果找到和subRoot相同根结点的结点的值,这里就可能是子树可能相同的地点,直接套判断相同的树的代码就可以了。

root防止为空是考虑到了在遍历的过程中可能一条路走到黑而导致触发空结点,return false是作为递归的终点,代表这条路找不到能与subRoot这个根结点相同的值。

如果找到了,就判断是否相同,不相同就一直遍历,直到遍历完整个树。

但是代码一碰见这蔫了,因为找到结点相同的了,就判断是不是相同,那肯定不同啊,相当于这样:

这样能通过就怪了。

想出来个这修改真是艰难,因为判断相等是肯定要有的,那干脆别以值相等做条件了,万一前面有跟上面这个例子一样,递归还没展开,先找到相等的值,那不直接炸了,如果递归展开了,就不用老担心:

这个图就是递归已经展开了才被拦截,最后肯定还是能找到只有1的subRoot。

所以直接一点,改成有相等的树才能返回true,不然就遍历完整棵树后返回false。

五、二叉树的遍历(前中后序)

遍历的思想基本没啥可讲了,但是放在oj题里可没有那么轻轻松松就能做出来:

比如前序遍历,最难的其实不是前序遍历完二叉树,注意看最后的返回值,要的是int*类型的

但是实际上这道题的意思是最后把遍历的数据放到数组最后返回数组的地址,这个数组还必须是动态开辟的数组,并且参数returnSize是用来确定遍历到的二叉树的结点的个数(最终存到数组内的元素个数)给远程服务器,前序遍历简单,但是一个一个放这些数据就有点讲究了。

上来问题就来了,那就是开辟多大空间的数组,那就免不了遍历二叉树去计算二叉树结点个数:

准备好以后就该前序遍历,并放到数组里:

最重要的就是写出来怎么把现在遍历到的根结点放到数组里,毕竟左子树右子树的遍历仅仅是递归而已。

容易想到的是必须带上偏移量,因为每次放置一个元素以后指针肯定要后移:

偏移量肯定不能传形参,你在Dispose这个函数里面往这次的arr+i所指向的位置存了以后就该++了,但是如果传值根本不能对偏移量i产生影响。

具体细节:

必须以i的地址为一个变量一直传给preOrder函数,因为每次递归如果不传i的地址,或者传值,前者得到的结果就是每次进入新的递归以后都会新建一个int i = 0;这样会造成偏移量实际没有后移,因为每次进新函数栈帧都是重新定义i;后者传值不会对偏移量产生影响,这个见过了。

成功通过,经过这道题掌握一种“常驻变量的改变”。

至于中序后序不多bb,调换个位置而已。

六、二叉树的构建和遍历

1.先序遍历字符串构建二叉树

2.二叉树中序遍历并输出

难的就是第一步,直接画图看看最终生成的是一棵什么样的树,并在画图过程中体会代码怎么写:

容易得到,如果碰不到空结点,肯定得一直根左右,那么就是这样的,接下来该返回到b了,因为c的根左右已经结束了:

紧接着就是遍历d的左右子树:

又碰到双空就得回头了:

再还原一下,检验正确。

最重要的递归构建树:

其实也没多高级,他说啥是啥,我们只需要注意先序遍历构建的顺序即可。

其它代码很简单,直接给出来了:

当然,这里输入确实偷懒了。

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

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

相关文章

开源:FTP同步工具

文章目录 简介功能特性Windows (EXE)从源代码构建依赖项Linux 构建Windows 构建 使用方法软件截图主界面FTP 设置快捷菜单定时设置 配置说明开发与贡献许可证 欢迎来到盹猫的博客 本篇文章主要介绍了 [开源:FTP同步工具] ❤博主广交技术好友,喜欢我的文章的可以关注…

视频质量测试点

目录 功能/UI 端侧性能 媒体质量 主观 客观 稳定性 兼容性 功能/UI 视频预览音频预览音视频同步全屏收藏打赏 端侧性能 PC端:内存占用、网络带宽占用等; 移动端:内存占用、功耗、发热、流量消耗等; 媒体质量 主观 音…

Ray框架:分布式AI训练与调参实践

Ray框架:分布式AI训练与调参实践 系统化学习人工智能网站(收藏):https://www.captainbed.cn/flu 文章目录 Ray框架:分布式AI训练与调参实践摘要引言框架架构解析1. 核心组件设计2. 关键技术实现2.1 动态资源调度2.2 …

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…

20250609在荣品的PRO-RK3566开发板的Android13下解决串口可以执行命令但是脚本执行命令异常的问题

20250609在荣品的PRO-RK3566开发板的Android13下解决串口可以执行命令但是脚本执行命令异常的问题 2025/6/9 20:54 缘起,为了跨网段推流,千辛万苦配置好了网络参数。 但是命令iptables -t filter -F tetherctrl_FORWARD可以在调试串口/DEBUG口正确执行。…

【C/C++】高效的位操作

位运算(Bitwise Operation)是直接对整数的二进制位进行操作的运算方式,在底层开发、性能优化、算法设计中广泛使用。 1 基本位运算符及含义 运算符名称示例(a5, b3)运算过程(二进制)结果&按…

后端下载限速(redis记录实时并发,bucket4j动态限速)

✅ 使用 Redis 记录 所有用户的实时并发下载数✅ 使用 Bucket4j 实现 全局下载速率限制(动态)✅ 支持 动态调整限速策略✅ 下载接口安全、稳定、可监控 🧩 整体架构概览 模块功能Redis存储全局并发数和带宽令牌桶状态Bucket4j Redis分布式限…

android app 一个 crash的解决过程!

一、日志: crash 2024-10-25 12:15:33.020 2113-2113 AndroidRuntime pid-2113 E FATAL EXCEPTION: main Process: com..workhome, PID: 2113 java.lang.RuntimeException: Unable to start activity ComponentInfo{com..w…

[Java 基础]Object 类

java.lang.Object 是 Java 所有类的直接或间接父类,Java 中每个类都默认继承 Object 类(即使你没写 extends Object)。 Object 中的常用方法: 方法名功能简介toString()返回对象的字符串表示equals(Object)判断两个对象是否“逻…

大数据学习(135)-Linux系统性指令

🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一…

【Fifty Project - D35】

今日完成记录 TimePlan完成情况7:00 - 7:40爬坡√8:30 - 11:30Rabbit MQ√17:30 - 18:30羽毛球√ RabbitMQ 消费者端如何保证可靠性? 消息投递过程出现网络故障消费者接收到消息但是突然宕机…

P3 QT项目----记事本(3.4)

3.4 文件选择对话框 QFileDialog 3.4.1 QFileDialog 开发流程 使用 QFileDialog 的基本步骤通常如下: 实例化 :首先,创建一个 QFileDialog 对象的实例。 QFileDialog qFileDialog;设置模式 :根据需要设置对话框的模式&…

学习笔记(26):线性代数-张量的降维求和,简单示例

学习笔记(26):线性代数-张量的降维求和,简单示例 1.先理解 “轴(Axis)” 的含义 张量的 “轴” 可以理解为 维度的方向索引 。对于形状为 (2, 3, 4) 的张量,3 个轴的含义是: 轴 0(axis0&…

健康档案实训室:构建全周期健康管理的数据基石

一、健康档案实训室建设背景 随着“健康中国2030”战略深入推进,健康档案作为居民健康数据的核心载体,在疾病预防、慢性病管理、医疗决策等领域的价值日益凸显。在此背景下,健康档案实训室建设成为职业院校对接政策要求、培养专业健康管理…

【MATLAB第119期】基于MATLAB的KRR多输入多输出全局敏感性分析模型运用(无目标函数,考虑代理模型)

【MATLAB第119期】基于MATLAB的KRR多输入多输出全局敏感性分析模型运用(无目标函数,考虑代理模型) 下一期研究SHAP的多输入多输出敏感性分析方法 一、SOBOL(无目标函数) (1)针对简单线性数据…

Linux常用文件目录命令

浏览目录命令: ls 、pwd目录操作命令:cd、mkdir、rmdir浏览文件命令:cat、more、less、head、tail文件操作命令:cp、rm、mv、find、grep、tar 浏览目录命令 ls ◼ 命令名称:ls ◼ 命令英文原意:list ◼ …

PIN码vs密码,电脑登录的快捷键你用对了吗?

你是否也遇到过这样的窘境:信心满满地输入电脑开机密码,屏幕却无情地提示“密码错误”。仔细一看,才发现登录界面悄悄地变成了要求输入“PIN码”。这种因为混淆了PIN码和账户密码而导致的开机失败,相信不少朋友都碰到过。 PIN码作…

【大模型科普】AIGC技术发展与应用实践(一文读懂AIGC)

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈人工智能与大模型应用 ⌋ ⌋ ⌋ 人工智能(AI)通过算法模拟人类智能,利用机器学习、深度学习等技术驱动医疗、金融等领域的智能化。大模型是千亿参数的深度神经网络(如ChatGPT&…