【算法练习Day19】二叉搜索树的最近公共祖先二叉搜索树中的插入操作删除二叉搜索树中的节点

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 二叉搜索树的最近公共祖先
  • 叉搜索树中的插入操作
  • 删除二叉搜索树中的节点
  • 总结:

二叉搜索树的最近公共祖先

235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)

看了题解,发现这道题与上一期相似的题的区别是,普通二叉树的查找最近公共节点,我们需要从二叉树的底部向上面遍历处理节点,而二叉搜索树,由于它自身拥有特定的排列顺序的缘故,我们要从上到下顺序的遍历处理节点,这一点上处理节点的顺序是不同的。我们根据搜索树的特征,将我们要查找的节点对应的值,与现在处在的节点值作比较,如果要查找的值大那么向右子树寻找,如果小向左子树递归

class Solution {
public:TreeNode* traversal(TreeNode* cur,TreeNode* p,TreeNode* q){if(cur==NULL){return cur;}if(cur->val>p->val&&cur->val>q->val){TreeNode* left=traversal(cur->left,p,q);if(left!=NULL){return left;}}if(cur->val<p->val&&cur->val<q->val){TreeNode* right=traversal(cur->right,p,q);if(right!=NULL){return right;}}return cur;}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {return traversal(root,p,q);}
};

代码比求普通二叉树略简短一些。递归通过对left和right的判断而看是否找到了p,q其中之一,向上返回,我们将处在p和q中间的第一次遇到的节点直接返回上去,因为第一次遍历到的那个p和q中间的节点一定处在p和q子树的中间节点,如果它再向左或者向右子树递归,那么就一定会错过p或者q中的其中一个。这就是为什么我们遇到数值在其中间直接返回,这也是根据了搜索树的特性。

叉搜索树中的插入操作

701. 二叉搜索树中的插入操作 - 力扣(LeetCode)

二叉搜索树中的插入操作,是略有理解难度的。起初在做这道题时,我们可能会被题目实例中的可以以多种答案提交而搞懵,有直接插入的,还有改变了二叉树结构插入进去的。这里我们需要明白,我们插入的任何节点都可以直接插入到该二叉搜索树的叶子节点处,也就是说不必要改变树的结构,因为改变树的结构的代码实现起来是有一些困难的。不理解为什么要插入的任何节点都可以在叶子节点插入的可以自行模拟一下。这里不必担心要插入的节点会和原二叉树某些节点值1相同,题目已经明确告诉了。

class Solution {
public:TreeNode* parent;void traversal(TreeNode* cur,int val){if(cur==nullptr){TreeNode* node=new TreeNode(val);if(val>parent->val){parent->right=node;}else{parent->left=node;}return;}parent=cur;if(cur->val>val){traversal(cur->left,val);}if(cur->val<val){traversal(cur->right,val);}return;}TreeNode* insertIntoBST(TreeNode* root, int val) {parent=new TreeNode(0);if(root==nullptr){root=new TreeNode(val);}traversal(root,val);return root;}
};

起初写代码时候,我是又自定义了一个void类型的函数,但是看了题解发现那样做很麻烦,直接在主函数上改动,是本题的最优解,当我们遍历到空的时候也就是找到了我们要插入的地点了,我们就直接原地创建一个节点然后返回上去,返回到上一层让上一层的节点链接我们要插入进去的节点即可。

class Solution {
public:TreeNode* insertIntoBST(TreeNode* root, int val) {if(root==NULL){TreeNode*node=new TreeNode(val);return node;}if(root->val>val){root->left=insertIntoBST(root->left,val);}if(root->val<val){root->right=insertIntoBST(root->right,val);}return root;}
};

这道题的向上递归逻辑就是,一层链接一层,由于我们没有改动二叉搜索树的结构,但是我觉得最好也要清楚,递归是如何一层一层向上返回的,它是每一次向上返回本层的节点,连接到上一层的left或者right处,当全部返回了之后,再把最开始的根节点root返回上去,作为返回值。

删除二叉搜索树中的节点

450. 删除二叉搜索树中的节点 - 力扣(LeetCode)

删除二叉树的节点面临着改变二叉树的结构,而无法避免。所以该类型题是较有难度的,删除二叉搜索的某节点,大致分为几种情况:要删除的节点并不在该二叉树中,删除的是叶子节点,删除的节点有左子树但是没有右子树,有右子树但没有左子树,最后一种情况是左右子树都有,其中最后一种是最复杂的。

找不到该节点我们可以直接向上返回,不对该二叉树做任何的改动,如果是叶子节点那么我们将null返回到上一层,让链接目标节点的节点某一方向指向空,这时候我们就直接把它从二叉树上取了下来,中间的两者,都是让上一层链接我们要删除的节点的不为空的子树部分,直接连接上去就可以了,避免都结构的改动。最后一种,我们需要向上一层返回的是:该节点右子树的最左子树链接要删除节点的左子树。因为我们要删除的节点的右子树节点一定都比我们的要删除的左子树节点值要大,而它右子树的最左侧子树的值应该是略大于要删除的节点,这样我们就只是在我们删除的节点的右子树的最左侧叶子节点处插入了一本来就有序的左子树,这样的改动最大限度的减小了结构处理的困难性。

class Solution {
public:TreeNode* deleteNode(TreeNode* root, int key) {if(root==nullptr){return root;}if(root->val==key){if(root->left==nullptr&&root->right==nullptr){delete root;return nullptr;}else if(root->left==nullptr){auto retNode=root->right;delete root;return retNode;}else if(root->right==nullptr){auto retNode=root->left;delete root;return retNode;}else{TreeNode* cur=root->right;while(cur->left!=nullptr){cur=cur->left;}cur->left=root->left;TreeNode* tmp=root;root=root->right;delete tmp;return root;}}if(root->val>key){root->left=deleteNode(root->left,key);}if(root->val<key){root->right=deleteNode(root->right,key);}return root;}
};

判断部分略多了一些,递归部分很少,这道题的递归返回逻辑仍然是,将本层的节点返回给上一层,然后上一层再链接当前节点的树。

总结:

今天我们完成了二叉搜索树的最近公共祖先、二叉搜索树中的插入操作、删除二叉搜索树中的节点三道题,相关的思想需要多复习回顾。接下来,我们继续进行算法练习。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

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

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

相关文章

vue七牛云视频直传

完成后样式&#xff1a; 下面的代码是我自己项目里面用到的&#xff0c;一些判断看自己情况去掉&#xff0c;用的是element-ui组件 安装 uuid 库。你可以使用 npm 或 yarn 来完成安装。在终端中执行以下命令&#xff1a; npm install uuidhtml部分 <el-upload class&quo…

Google zxing 生成带logo的二维码图片

环境准备 开发环境 JDK 1.8SpringBoot2.2.1Maven 3.2 开发工具 IntelliJ IDEAsmartGitNavicat15 添加maven配置 <dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.0</version> </…

2023年09月 C/C++(七级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 Python编程&#xff08;1~6级&#xff09;全部真题・点这里 第1题&#xff1a;红与黑 有一间长方形的房子&#xff0c;地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上&#xff0c;只能向相邻的黑色…

新式茶饮品牌如何写出生活感软文

居民消费水平的提升使新式茶饮品牌的市场不断扩张&#xff0c;在竞争激烈的茶饮市场中&#xff0c;品牌提高知名度的主要方式之一就是软文营销&#xff0c;而生活感软文是茶饮软文中较为常见的类型&#xff0c;它能有效拉进品牌与消费者之间的距离&#xff0c;那么新式茶饮品牌…

24字符串-kmp寻找重复子串

目录 字符串匹配——kmp算法 LeetCode之路——459. 重复的子字符串 分析&#xff1a; 字符串匹配——kmp算法 强烈建议参考Carl的讲解&#xff1a; 视频讲解版&#xff1a;帮你把KMP算法学个通透&#xff01;&#xff08;理论篇&#xff09;(opens new window) 视频讲解版&…

近地面无人机植被定量遥感与生理参数反演

目录 专题一 近十年近地面无人机植被遥感文献分析、传感器选择、观测方式及质量控制要点 专题二 辐射度量与地物反射特性 专题三 无人机遥感影像辐射与几何处理 专题四 光在植被叶片与冠层中的辐射传输机理及平面模型应用 专题五 植被覆盖度与叶面积指数遥感估算 更多应用…

【开源】给ChatGLM写个,Java对接的SDK

作者&#xff1a;小傅哥 - 百度搜 小傅哥bugstack 博客&#xff1a;bugstack.cn 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 大家好&#xff0c;我是技术UP主小傅哥。 清华大学计算机系的超大规模训练模型 ChatGLM-130B 使用效果非常牛&…

「网络编程」网络层协议_ IP协议学习_及深入理解

「前言」文章内容是网络层的IP协议讲解。 「归属专栏」网络编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、IP协议简介二、IP协议报头三、IP网段划分&#xff08;子网划分&#xff09;四、特殊的IP地址五、IP地址的数量限制六、私有IP地址和公网IP地址七、路由八、分…

【Python】Python语言基础(中)

第十章 Python的数据类型 基本数据类型 数字 整数 整数就是整数 浮点数 在编程中&#xff0c;小数都称之为浮点数 浮点数的精度问题 print(0.1 0.2) --------------- 0.30000000000000004 ​​1.可以通过round()函数来控制小数点后位数 round(a b)&#xff0c;则表示…

spring6使用启用Log4j2日志框架

文章目录 Log4j2日志概述1. 引入Log4j2依赖2. 加入日志配置文件3. 测试 Log4j2日志概述 在项目开发中&#xff0c;日志十分的重要&#xff0c;不管是记录运行情况还是定位线上问题&#xff0c;都离不开对日志的分析。日志记录了系统行为的时间、地点、状态等相关信息&#xff…

[Python小项目] 从桌面壁纸到AI绘画

从桌面壁纸到AI绘画 一、前言 1.1 确认问题 由于生活和工作需要&#xff0c;小编要长时间的使用电脑&#xff0c;小编又懒&#xff0c;一个主题用半年的那种&#xff0c;所以桌面壁纸也是处于常年不更换的状态。即时改变主题也是在微软自带的壁纸中选择&#xff0c;而这些自…

LaTeX 公式与表格绘制技巧

LaTeX 公式与绘图技巧公式基本可以分为 单一公式单一编号单一公式按行编号单一公式多个子编号单一公式部分子编号分段公式现在给出各自的代码单一公式单一编号 公式1&#xff1a;equationaligned\begin{equation}\begin{aligned}a&bc\\b&a2\\c&b-3\end{aligned}\en…

如何使用前端包管理器(如npm、Yarn)?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

c# xml 参数读取的复杂使用

完整使用2 生产厂家里面包含很多规格型号,一个规格型号里面包含很多出厂序列号,点击下一步如果检测到填充的和保存的不一样 就新增一条(如检测到生产厂家相同,但是规格型号不同,就新增一组规格型号)。 界面一:新增界面 界面2 删除界面 界面一:新增界面 load 其中…

spark读取hive表字段,区分大小写问题

背景 spark任务读取hive表&#xff0c;查询字段为小写&#xff0c;但Hive表字段为大写&#xff0c;无法读取数据 问题错误: 如何解决呢&#xff1f; In version 2.3 and earlier, when reading from a Parquet data source table, Spark always returns null for any column …

网络工程师知识点3

41、各个路由协议&#xff0c;在华为设备中的优先级&#xff1f; 直连路由 0 OSPF 10 静态 60 42、OSPF&#xff1a;开放式最短路径优先路由协议&#xff0c;使用SPF算法发现和计算路由 OSPF的优点&#xff1a; 1、收敛速度快&#xff0c;无路由自环&#xff0c;适用于大型网络…

linux usb驱动移植(1)

1. USB总线 1.1 usb总线定义 在linux 设备模型中&#xff0c;总线由bus_type 结构表示&#xff0c;我们所用的 I2C、SPI、USB 都是用这个结构体来定义的。该结构体定义在 include/linux/device.h文件中&#xff1a; struct bus_type {const char *name;const c…

【计算机组成体系结构】电路基本原理与加法器设计

一、算术逻辑单元—ALU 1.基本的逻辑运算&#xff08;1bit的运算&#xff09; 基本逻辑运算分为&#xff0c;与、或、非。大家应该很熟悉了&#xff0c;与&#xff1a;全1为1&#xff0c;否则为0。或&#xff1a;全0为0&#xff0c;否则为1。非&#xff1a;取反。三个基本的逻…

Git纯操作版 项目添加和提交、SSH keys添加、远程仓库控制、冲突解决、IDEA连接使用

Git 文章目录 Git项目简单克隆通用操作添加和提交回滚分支变基分支优选 远程项目推送认证抓取、拉取和冲突解决 IEDA类软件连接 最近学原理学的快头秃了&#xff0c;特此想出点不讲原理的纯操作版&#xff0c;不过还是放个图吧 项目简单克隆 git在本人日常中最重要的功能还是…

idea 启动出现 Failed to create JVM JVM Path

错误 idea 启动出现如下图情况 Error launching IDEA If you already a 64-bit JDK installed, define a JAVA_HOME variable in Computer > System Properties> System Settings > Environment Vanables. Failed to create JVM. JVM Path: D:\Program Files\JetB…