【算法练习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.mzph.cn/news/103661.shtml

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

相关文章

Avalonia常用小控件Svg

1.项目下载地址&#xff1a;https://gitee.com/confusedkitten/avalonia-demo 2.UI库Semi.Avalonia&#xff0c;项目地址 https://github.com/irihitech/Semi.Avalonia 3.SVG库&#xff0c;Avalonia.Svg.Skia&#xff0c;项目地址 https://github.com/wieslawsoltes/Svg.Ski…

【数据库——MySQL(实战项目1)】(4)图书借阅系统——触发器

目录 1. 简述2. 功能代码2.1 创建两个触发器&#xff0c;分别在借出或归还图书时&#xff0c;修改借阅人表中的已借数目(附加&#xff1a;借阅人表的总借书数、图书表的借阅次数以及更新图书表的图书状态为(已借出/在架上))字段&#xff1b;2.2 创建触发器&#xff0c;当借阅者…

redis 哨兵 sentinel(一)配置

sentinel巡查监控后台master主机是否故障&#xff0c;如果故障根据投票数自动将某一个从库转换为新主库&#xff0c;继续对外服务 sentinel 哨兵的功能 监控 监控主从redis库运行是否正常消息通知 哨兵可以将故障转移的结果发送给客户端故障转移 如果master异常&#xff0c;则…

IOS17 轻松签全能签还能不能用?多开能否使用?升级后微信底栏消失怎么办?BY:后厂村路灯

从iphone15还没出就有小伙伴们追着问&#xff0c; 到现在也有人一直再问iOS17能不能用&#xff0c;看来换手机的人很多呀。 这里统一回答一下&#xff1a;“iOS17苹果签名可以用&#xff0c;多开也可以用”但是还是有些地方注意。 如果你是16系统直接升级刀17就可以&#xff…

使用 Splashtop 驾驭未来媒体和娱乐

在当今时代&#xff0c;数字转型不再是可选项&#xff0c;而是必选项。如今&#xff0c;媒体与娱乐业处于关键时刻&#xff0c;正在错综复杂的创意、技术和远程协作迷宫之中摸索前进。过去几年发生的全球事件影响了我们的日常生活&#xff0c;不可逆转地改变了行业的运作方式&a…

给你一个项目,你将如何开展性能测试工作?

一、性能三连问 1、何时进行性能测试&#xff1f; 性能测试的工作是基于系统功能已经完备或者已经趋于完备之上的&#xff0c;在功能还不够完备的情况下没有多大的意义。因为后期功能完善上会对系统的性能有影响&#xff0c;过早进入性能测试会出现测试结果不准确、浪费测试资…

【C++STL基础入门】list基本使用

文章目录 前言一、list简介1.1 list是什么1.2 list的头文件 二、list2.1 定义对象2.2 list构造函数2.3 list的属性函数 总结 前言 STL&#xff08;Standard Template Library&#xff09;是C标准库的一个重要组成部分&#xff0c;提供了一套丰富的数据结构和算法&#xff0c;可…

【Lombok的Bug记录】前端传的有值,但是到后端就全为空了

项目场景&#xff1a; 项目背景&#xff1a;使用Data注解标注类 问题描述 前端传的有值&#xff0c;但是到后端就全为空了 原因分析&#xff1a; AName和aName生成的set方法名是一样的&#xff0c;所以换名字就行了&#xff01; 解决方案&#xff1a; 属性不要写成xXxx的形式…

【伪彩色图像处理】将灰度图像转换为彩色图像研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

YB4014是可以对单节磷酸铁锂电池进行恒流/恒压充电管理的集成电路。

概述&#xff1a; YB4014是可以对单节磷酸铁锂电池进行恒流/恒 压充电管理的集成电路。该器件内部包括功率晶 体管&#xff0c;不需要外部的电流检测电阻和阻流二极管 YB4014只需要极少的外围元器件&#xff0c;非常适合于 便携式应用的领域。热调制电路可以在器件的功 耗比较大…

flutter开发入门,windows环境安装,耗时一天解决各种bug,终于成功

首先说明要安装的环境&#xff1a;java8必须&#xff0c;android studio&#xff0c;chrome是开发安卓和web是必须的 java8的下载地址&#xff1a;https://www.java.com/en/download/、 java8蓝奏云下载地址&#xff1a;jre-8u381-windows-x64.exe - 蓝奏云 flutter国内环境…

Spring Boot 中的 Redis 数据操作配置和使用

Spring Boot 中的 Redis 数据操作配置和使用 Redis&#xff08;Remote Dictionary Server&#xff09;是一种高性能的开源内存数据库&#xff0c;用于缓存、消息队列、会话管理和数据存储。在Spring Boot应用程序中&#xff0c;Redis被广泛用于各种用例&#xff0c;包括缓存、…

下载安装Ipa Guard

下载安装Ipa Guard 可以前往ipaguard工具官网下载&#xff0c;工具是免费下载&#xff0c;免费体验使用的。下载地址是https://www.ipaguard.com。 下载后解压工具便ok了&#xff0c;工具是绿色软件&#xff0c;无需其他安装流程。双击Ipa Guard.exe 启动ipaguard。 ipaguard…

Java语法基础案例(二)

目录 案例六&#xff1a;抢红包 案例七&#xff1a;找素数 方法一&#xff1a; 方法二&#xff1a; 方法三&#xff1a; 案例八&#xff1a;实现双色球 关于本项目所用所有方法的解释&#xff1a; 案例六&#xff1a;抢红包 一个大V直播时发起了抢红包活动&#xff0c;分…

2023年中国固废处理行业研究报告

第一章 行业概况 1.1 定义 固体废物处理是一个日益重要的领域&#xff0c;随着中国城市化进程的加速和工业产值的持续增长&#xff0c;固体废物的产生量也在不断上升。根据《固体废物污染环境防治法》的定义&#xff0c;固体废物包括了人类在生产、生活和其他活动中产生的固态…

AI低代码维格云甘特视图怎么用?

甘特视图,以日期为横轴展示任务持续时长和先后顺序,简称甘特图。 项目管理过程中,合理分配任务和资源至关重要,使用甘特图,妥当解决以下场景: 想知道整个项目的周期多长,哪些任务对项目的周期影响最大; 想知道每个任务的时间有多长,任务的优先级和依赖关系是什么; 想…

基于深度学习的“语义通信编解码技术”框架分类

目录 基于神经网络的语义提取基于神经网络的语义信源编码基于神经网络的语义信源信道联合编码基于神经网络的语义编码与数字调制联合设计参考文献 基于神经网络的语义提取 在现有的信源编码前端加上一个语义提取神经网络[53] &#xff0c;如图所示。语义提取神经网络的输入是原…

接口自动化测试框架搭建【附教程加源码】

1 接口测试 接口测试是对系统或组件之间的接口进行测试&#xff0c;主要是校验数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及相互逻辑依赖关系。 接口自动化相对于UI自动化来说&#xff0c;属于更底层的测试&#xff0c;这样带来的好处就是测试收益更大&#xff…

【TensorFlow2 之015】 在 TF 2.0 中实现 AlexNet

一、说明 在这篇文章中&#xff0c;我们将展示如何在 TensorFlow 2.0 中实现基本的卷积神经网络 \(AlexNet\)。AlexNet 架构由 Alex Krizhevsky 设计&#xff0c;并与 Ilya Sutskever 和 Geoffrey Hinton 一起发布。并获得Image Net2012竞赛中冠军。 教程概述&#xff1a; 理论…

OpenCV实现答题卡自动打分!

目录 1&#xff0c;主要原理以及函数介绍 全部代码&#xff0c;以 2 &#xff0c; 实现过程 3&#xff0c;结果展示 1&#xff0c;主要原理以及函数介绍 ap argparse.ArgumentParser() 创建一个ArgumentParser对象&#xff0c;并将其赋值给变量ap。这个对象可以接受我们的脚…