java 递归从子节点删除父节点_LeetCode450. 删除二叉搜索树中的节点

469c8bc5c1051634d7c70269c10f5887.png

删除一个二叉搜索树中的节点,需要进行情况的分类讨论,看一下将这个节点删除之后是否需要对二叉搜索树进行调整(为了保持树的连接和维持二叉搜索树的性质)。

(1)如果删除的是一个叶子节点,那问题不大,因为它没有左子树和右子树,直接返回NULL就行了,表示它没了。

(2)如果要删除的节点,左右子树都存在,那麻烦了,删除这个节点是需要进行调整的,删除的这个节点可以用它左子树的最大值或者右子树的最小值来替代(为了 维持二叉搜索树的性质),这里我们用右子树的最小值来代替这个被删除的最小值。然后递归地到右子树删除那个原来右子树中的最小值(因为它已经滚到那个被删除的节点上了)。

(3)如果要删除的节点左子树不存在,那我们直接让这个被删除的节点的父节点的右指针指向被删除节点的右孩子就好了。也就是跳过了这个被删除的节点,表示这个节点被删除了。 这一步操作直接用root = root -> right;就可以完成。

(4)如果被删除的节点右子树不存在,那就类似(3),直接用root = root -> left;表示将被删除的节点的父节点的左指针指向被删除节点的左孩子,表示将这个节点删除。

代码如下:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:TreeNode* findSmallest(TreeNode* root) {            // 找到以root为根的树中的最小值,这个函数是为了在删除某个节点且这个节点右子树不为空时,找到右子树中的最小值if(root == NULL) {      return NULL;} else if(root -> left != NULL) {              // 如果左子树不为空,这最小值在左子树中,递归地去左子树中寻找最小值return findSmallest(root -> left);}return root;                                    // 如果左子树为空,这最小值就是root,这是由二叉搜索树的性质决定的}TreeNode* deleteNode(TreeNode* root, int key) {if(root == NULL) {return NULL;} else if(key < root -> val) {                   // 要删除的值小于根节点的值,递归地到左子树中删除这个节点root -> left = deleteNode(root -> left, key);} else if(key > root -> val) {                  // 要删除的值大于根节点的值,递归地到右子树中删除这个节点root -> right = deleteNode(root -> right, key);} else {if(root -> left == NULL && root -> right == NULL) {   // 如果被删除的节点是叶节点,直接删除这个节点,返回NULL即可return NULL;} else if(root -> left != NULL && root -> right != NULL) { // 如果被删除的节点左、右子树都不为空TreeNode* temp = findSmallest(root -> right);          // 那就找到右子树中最小的值(也就是被删除的节点的中序后继),用这个节点代替被删除的节点root -> val = temp -> val;                                    root -> right = deleteNode(root -> right, root -> val);   // 然后递归地到右子树中删除这个节点} else if(root -> left != NULL) {                           // 如果左子树不为空,这直接连接被删除的节点的父节点的左指针到这个左子树上root = root -> left;} else if(root -> right != NULL) {                          // 右子树不为空时同理root = root -> right;}}return root;}
};

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

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

相关文章

1. [文件]- 文件类型,文件open模式

1.文件类型&#xff1a;文本文件和二进制文件 硬盘中的文件保存为01010101格式&#xff0c;一般读取文件是把文件从硬盘中读取到内存中。 文本文件需要进行格式转换才能读取出来。二进制文件一般用于传输二进制文件&#xff1a;视频图片 2.文件打开模式 几种不同的读取和遍历文…

c语言鼠标移动响应,CSS鼠标响应事件经过、移动、点击示例介绍

几种鼠标触发CSS事件。说明&#xff1a;onMouseDown 按下鼠标时触发onMouseOver 鼠标经过时触发onMouseUp 按下鼠标松开鼠标时触发onMouseOut 鼠标移出时触发onMouseMove 鼠标移动时触CSS 鼠标响应事件.Off{ background-color: #00FF66; padding:100px;}.up{background-color: …

node安装node-sass失败,配置淘宝源

node-sass 安装失败的原因是因为无法下载 .node 文件&#xff0c;解决办法就很简单了&#xff0c;就是我们把文件下载路径复制一份到浏览器里&#xff0c;然后使用浏览器下载文件就可以了。 具体方法 1.从node命令行中复制 .node文件下载链接并在浏览器打开下载文件https:/…

django 日志配置

django 日志配置 LOGGING { version: 1, disable_existing_loggers: False, formatters: { standard: { format: %(levelname)s %(asctime)s %(pathname)s %(filename)s %(funcName)s %(lineno)d: %(message)s }, # INFO 2016-09-03 16:25:20,067 /home/ubuntu/mysite/views.p…

带有Atomikos示例的Tomcat中的Spring JTA多个资源事务

在本教程中&#xff0c;我们将向您展示如何使用Atomikos Transaction Manager在Tomcat服务器中实现JTA多个资源事务。 Atomicos事务管理器为分布式事务提供支持。 这些是多阶段事务&#xff0c;通常使用多个数据库&#xff0c;必须以协调的方式提交。 分布式事务由XA standard描…

mac vs 返回上一步_mac电脑打不开应用程序的解决方法

mac电脑跟windows电脑一样&#xff0c;经常会出现打不开应用程序的情况&#xff0c;并且提示“因为它来自身份不明的开发者”&#xff0c;也不知道哪里出现问题&#xff1f;由于MAC系统与windows界面不一样&#xff0c;很多小编不懂怎么操作&#xff1f;为此&#xff0c;小编给…

C#DES加密

记录一下 DES加密 public static string DESEncrypt(string Data, string key){return DESEncrypt(Data, key, "utf-8");}/// <summary>/// DES加密算法/// </summary>/// <param name"Data">加密明文</param>/// <param name&…

c语言链表有没有哨兵的区别,链表中的哨兵(sentinel)

哨兵节点广泛应用于树和链表中&#xff0c;如伪头、伪尾、标记等&#xff0c;它们是纯功能的&#xff0c;通常不保存任何数据&#xff0c;其主要目的是使链表标准化&#xff0c;如使链表永不为空、永不无头、简化插入和删除。问题&#xff1a;删除链表中等于给定值val的所有节点…

jquery 获取标签名(tagName)

如果是为了取到tagName后再进行判断&#xff0c;那直接用下面的代码会更方便&#xff1a; $(element).is(input) 如果是要取到标签用作到别的地方&#xff0c;可以使用一下代码&#xff1a; $(element)[0].tagName或&#xff1a;$(element).get(0).tagName 转载请注明&#xff…

番石榴条纹类的细粒度并发

这篇文章将介绍如何使用Guava中的Striped类来实现更细粒度的并发。 ConcurrentHashMap使用条带化锁定方法来增加并发性&#xff0c;并且Striped类通过赋予我们具有条带化Locks &#xff0c; ReadWriteLocks和Semaphores的能力来扩展此主体。 当访问对象或数据结构&#xff08;例…

iOS-----------关于组件化

打一个比较形象的比喻&#xff0c;把APP比作我们的人体&#xff0c;把胳膊、大腿、心、肝、肺这些人体器官比作组件&#xff0c;各个器官分别负责他们各自的功能&#xff0c;但是他们之间也有主次之分&#xff0c;试想我们的胳膊、大腿等是不能独立完成某个任务的&#xff0c;必…

scrapy 安装

直接命令pip install scrapy安装&#xff0c;提示失败 Failed building wheel for Twisted... Microsoft Visual C 14.0 is required...等等 网上搜索一大摞windows下安装scrapy的资料&#xff0c;实践后终于大功告成&#xff0c;现分享出来 1.首先下载scrapy的whl包&#xff1…

leetcode 罗马数字转整数

罗马数字包含以下七种字符&#xff1a;I&#xff0c;V&#xff0c;X&#xff0c;L&#xff0c;C&#xff0c;D 和M。 字符数值I1V5X10L50C100D500M1000例如&#xff0c; 罗马数字 2 写做II &#xff0c;即为两个并列的 1。12 写做XII &#xff0c;即为 X II 。 27 写做 XXVII, …

android 自定义switch控件,Android中switch自定义样式

android 原生开关按钮控件 Switch 提供样式自定义方式&#xff0c;可供我们修改为适合我们开发使用的样式控件&#xff0c;自定义样式过程如下:自定义switch切换drawable新建swith_thumb.xml文件自定义switch轨道drawable新建switch_track.xmln文件,轨迹如果在选中与否过程并没…

具有瞬态属性的视图对象的钝化和激活

在应用程序模块的钝化/激活周期内&#xff0c;框架也会钝化并激活视图对象。 通常&#xff0c;框架保存有关VO状态&#xff0c;当前行&#xff0c;绑定变量值等的信息。 但是没有数据。 激活视图对象后&#xff0c;将重新执行VO的查询&#xff0c;并重新获取数据。 在大多数情况…

jsonobject修改key的值_JSON字符串操作移除空串更改key/value的介绍

对于JSON字符串的操作。移除键值、添加属性。//删除JSON对象value值var json[.....];delete(json[key]);或者delete(json.key);//添加对象objectjson.objectvalue;或者json[object]value;如果数据是查询数据库得到的&#xff0c;那么可能会存在空值&#xff0c;for循环JSON数据…

pre标签的样式

你可能正在使用 <pre> 标签。这是一个 HTML 中非常特别的标签&#xff0c;它允许其中的空格真正显示出来。例如&#xff1a;四个空格将真实显示成四个空格。这不同于其他标签通常的做法&#xff0c;其他标签会将之间的空白压缩成一个。从这一点来说&#xff0c;<pre&g…

从Hotspot JIT编译器打印生成的汇编代码

有时&#xff0c;在对Java应用程序进行性能分析时&#xff0c;有必要了解Hotspot JIT编译器生成的汇编代码。 这对于确定已做出的优化决策以及我们的代码更改如何影响生成的汇编代码非常有用。 在调试并行算法以确保已按预期应用可见性规则时&#xff0c;知道何时发出什么指令也…

js的闭包

function a(){var n 0;this.inc function () {n; console.log(n);}; } var c new a(); c.inc(); //控制台输出1 c.inc(); //控制台输出2 什么是闭包&#xff1f;这就是闭包&#xff01;&#xff01;有权访问另一个函数作用域内变量的函数都是闭包。当函数可以记住并访…

Background-size完美兼容IE

CSS3 新增的 background-size 是一个很有用的属性&#xff0c;用于定义背景图片的尺寸&#xff0c;有了这个属性&#xff0c;你就可以任意指定背景图片的大小。其中最常用的值应该要数 cover 了&#xff0c;该值能让背景图片缩放至填满整个容器&#xff0c;即使是图片面积小于容…