第二十四天 | 501.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

题目:501.二叉搜索树中的插入操作

自己有一定的思路,但是遇到的难点:

        可以找到val应该插入的位置,但如何建立新节点的结构呢?也就是说新建立的node应该怎么指,是搭建左孩子还是右孩子?又是应该被pre所指还是被root所指呢?

写出了如下代码:

class Solution {
public:
    TreeNode *pre = NULL;
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(root == NULL) return NULL;

        TreeNode *left = insertIntoBST(root->left, val);
        if(pre == NULL){
            if(root->val > val){
                TreeNode *node = new TreeNode(val);
                root->left = node;
                return root;
            }else{
                pre = root;
            }
        }else{
            if(root->val > val && pre->val < val){
                TreeNode *node = new TreeNode(val);
                root->left = node;
                return root;
            }else{
                pre = root;
            }
        }
        
        TreeNode *right = insertIntoBST(root->right, val);
        if(left != NULL && right == NULL) return left;
        if(left == NULL && right != NULL) return right;

        return NULL;
    }
};

本题最简单的思路:

        不用考虑题干所说改变二叉树结构、插入位置有多种情况那么复杂,将所插入的值都插入在最底层,即最底层一定可以找到满足条件的位置。

        按照二叉树的特性进行向下搜索递归,一直到最低点,此时建立新节点,并将建立的节点返回,这是终止条件。

        对于单层递归逻辑,应该如所示进行判断,按照大小进行搜索,每一层将节点返回。

有一个难以理解的地方,返回的节点应该用什么接住?

        此时可以用最底层的返回值来模拟一下:新建立的节点被返回了,应该接在上一层的root->left或者root->right,即返回给root->left或者root->right。

代码如下:

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);
            return root;
        }
        if(root->val < val){
            root->right = insertIntoBST(root->right, val);
            return root;
        }

        return root;
    }
};

可看出本题的遍历顺序其实不属于前、中或者后,而是根据搜索二叉树的特性向下搜索到目标位置。

450.删除二叉搜索树中的节点(难)

删除节点要考虑五种情况:

        1.没有找到需要删除的节点。

        2.需要删除的节点是叶子节点,左为空右也为空。

        3.需要删除的节点,其左不为空右为空。

        4.需要删除的节点,其左为空右不为空。

        5.需要删除的节点其左右都不为空。(此种情况最难,需要大幅改动二叉树结构)

终止条件比较复杂(因为删除节点的操作就在终止条件里):

        ①如果遍历到NULL,说明本条路径没有找到目标节点,返回 NULL

        如果找到需要删除的节点(key):

                ②判断是不是叶子节点。return NULL,一定要理解为什么要return NULL?其实是将NULL返回给上一层的子树。

                ③如果左不为空右为空,返回该节点的子树,同样的,该节点的子树返回给了哪里?答:赋值给了上一层。

                ④左为空右不为空同理。

               ⑤左右都不为空:要找到最接近待删除节点那个数的数(比key大一点点或小一点点任选其一),定义一个cur作为指针去遍历到最接近待删除节点那个数的数,然后改动树的结构(详见代码)。最后记得释放内存。

单层递归逻辑:

        利用二叉树的特性,向下遍历,注意递归的返回值要用什么接住?

注意:在自己写代码时很容易在最最最后,即单层递归之后忘写返回值,有时也不知道该返回什么。像本题就应该返回root(其实我个人理解,在出第一层之外之不可能执行最后这个return的,必定都会在上面的语句中都返回了。这一句话主要是为了保证第一层函数有返回值,就是说执行完所有的递归完成了删除节点的操作后,会将新二叉树的根节点返回。不然会报错:这个函数没有返回值)(前面说的有问题,每一层递归(除了判断终止条件的时候)都会执行这个return语句,将重新构造的树的root返回给上一层)

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if(root == NULL) return NULL; // 第一种情况:没找到删除的节点,遍历到空节点直接返回了
        if(root->val == key){
            // 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
            if(root->left == NULL && root->right == NULL){
                delete root;
                return NULL;
            }
            // 第三种情况:其左孩子不为空,右孩子为空,删除节点,右孩子补位 ,返回右孩子为根节点
            else if(root->left != NULL && root->right == NULL){
                auto retNode = root->left;
                delete root;
                return retNode;
            }
            // 第三种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点
            else if(root->left == NULL && root->right != NULL){
                auto retNode = root->right;
                delete root;
                return retNode;
            }
            // 第五种情况:左右孩子节点都不为空,则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置
            // 并返回删除节点右孩子为新的根节点。
            else{
                TreeNode *cur = root->right;          //现在要将root删除,企图将root->left接在右子树的下面
                while(cur->left) cur = cur->left;     //如果cur->left还存在,说明此时cur还不是比root大且理root最近的节点
                cur->left = root->left;       // 把要删除的节点(root)左子树放在cur的左孩子的位置
                TreeNode *tmp = root;      // 把root节点保存一下,下面来删除
                root = root->right;        // 返回旧root的右孩子作为新root
                delete tmp;                // 释放节点内存(这里不写也可以,但C++最好手动释放一下吧)
                return root;
            }
        }
        if(root->val > key) root->left = deleteNode(root->left, key);    //deleteNode函数有返回值,其返回值需要用root->left接住
        if(root->val < key) root->right = deleteNode(root->right, key);
        return root;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

k8s证书续期

证书即将到期了如何进行证书续签 k8s版本V1.23.6 1.查看证书期限 kubeadm certs check-expiration如果证书即将到期&#xff0c;此处的天数应该是几天&#xff0c;在过期之前进行续期&#xff0c;保证集群的可用 2. 备份证书 避免出现问题可以回退 cp -r /etc/kubernetes …

Swift知识点(三)

11. init、deinit、可选链、协议、元类型 构造和析构 构造方法 构造方法是一种特殊的方法 一个对象创建完毕后&#xff0c;都需要调用构造方法进行初始化&#xff08;比如属性的初始化&#xff09; 验证&#xff1a;init方法是在对象创建完毕的时候调用 回到存储属性 在对…

【全开源】国际版JAVA游戏陪玩系统源码陪练APP源码H5源码电竞系统源码支持Android+IOS+H5

国际版游戏陪玩系统&#xff1a;连接全球玩家的桥梁 在数字化时代&#xff0c;游戏已成为全球范围内跨越文化和地域的桥梁。随着游戏产业的蓬勃发展&#xff0c;玩家们对于游戏体验的需求也日益多样化。为了满足这一市场需求&#xff0c;我们隆重推出“国际版游戏陪玩系统”&a…

electron的Remote模块

03 【electron的Remote模块】 在渲染进程里&#xff08;比如index.html里面加载了一些js文件&#xff0c;那里面的js如果要使用到 BrowserWindow 这些属性的话就必须使用 remote&#xff09; 使用 remote 模块, 你可以调用 main 进程对象的方法 1.electron14.0之前版本使用 …

【微信小程序开发(从零到一)【婚礼邀请函】制作】——邀请函界面的制作(2)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

一篇文章拿下 Redis缓存穿透,缓存击穿,缓存雪崩

文章目录 ☃️缓存击穿❄️❄️解决方案一、使用锁❄️❄️解决方案二、逻辑过期方案❄️❄️解决方案三、永不过期 主动更新❄️❄️解决方案四、接口限流❄️❄️实战❄️❄️❄️利用互斥锁解决缓存击穿问题❄️❄️❄️利用逻辑过期解决缓存击穿问题 ☃️缓存穿透❄️❄️缓…

【python】将json内解码失败的中文修改为英文(‘utf-8‘ codec can‘t decode,labelme标注时文件名未中文)

出现问题的场景&#xff1a; 语义分割数据集&#xff0c;使用labelme工具进行标注&#xff0c;然后标注图片存在中文名&#xff0c;导致json标签文件写入中文图片名&#xff0c;从而解析失败。 代码解析json文件时&#xff0c;出现报错&#xff1a; python脚本需求&#x…

org.postgresql.util.PSQLException: 错误: 关系 “dual“ 不存在

springboot 项目连接 postgreps&#xff0c;启动时报错 org.postgresql.util.PSQLException: 错误: 关系 "dual" 不存在。 查阅资料后发现这是由配置文件中的配置 datasource-dynamic-druid-validationQuery 导致的 spring:datasource:druid:stat-view-servlet:ena…

SDL系列(四)—— 事件机制

事件循环 大多数多媒体程序依靠 事件系统 来处理输入。 SDL 为处理输入事件提供了灵活的 API 。 本质上&#xff0c; SDL 将来自设备&#xff08;如键盘&#xff0c;鼠标或控制器&#xff09;的输入记录为 事件 &#xff0c;将它们存储在 “ 事件队列 ”中。 您可以将此…

使用Xterm实现终端构建

————html篇———— // 需要使用Xterm Xterm的官网&#xff1a; Xterm.js 新建项目 增加基本文件 下载 框架 npm init -y Xterm依赖 npm install xterm/xterm 参考文档写的代码 贴入代码 <html><head><link rel"stylesheet" href"nod…

【prometheus】prometheus基于consul服务发现实现监控

目录 一、consul服务发现简介 1.1 consul简介 二、prometheus配置 2.1 node-exporter服务注册到consul 2.2 修改prometheus配置文件 【Prometheus】概念和工作原理介绍_prometheus工作原理-CSDN博客 【Prometheus】k8s集群部署node-exporter 【prometheus】k8s集群部署p…

企业微信hook接口协议,ipad协议http,大文件网络上传

大文件网络上传 参数名必选类型说明url是String网络图片地址 请求示例 {"uuid":"2b0863724106a1160212bd1ccf025295","authkey":"0AAxxx031", "filekey":"346b7bff-08d5-4ac2-bc67-fd10e3eb2388", "fileur…

六西格玛绿带培训:解锁质量工程师的职场新篇章

在质量管理这条道路上&#xff0c;我们或许都曾有过这样的疑问&#xff1a;为何付出了同样的努力&#xff0c;却未能获得预期的回报&#xff1f;当我们看到身边的同行们逐渐步入高薪的行列&#xff0c;而自己却似乎陷入了职业的泥沼&#xff0c;这种对比无疑令人倍感焦虑。然而…

win10安装docker

控制面板-> 程序和功能 最好是是管理员进入cmd PS C:\Windows\system32> wsl --status PS C:\Windows\system32> wsl --install -d Ubuntu 正在安装: 适用于 Linux 的 Windows 子系统 已安装 适用于 Linux 的 Windows 子系统。 正在安装: Ubuntu 已安装 Ubuntu。 请…

银行风险系统的全面解析:功能作用与系统间的互联互通

银行风险管理系统是银行为控制风险而建立的一套重要系统&#xff0c;主要用于评估、监测和控制银行面临的各种风险&#xff0c;包括信用风险、市场风险、操作风险等。 一、主要功能 风险识别&#xff1a;系统首先识别在业务开展中可能会面临的各种风险。这通常涉及对客户信息、…

Kotlin核心编程知识点-02-面向对象

文章目录 1.类和构造方法1.1.Kotlin 中的类及接口1.1.1.Kotlin 中的类1.1.2.可带有属性和默认方法的接口 1.2.更简洁地构造类的对象1.2.1.构造方法默认参数1.2.2.init 语句块1.2.3.延迟初始化&#xff1a;by lazy 和 lateinit 1.3.主从构造方法 2.不同的访问控制原则2.1.限制修…

【虚拟仿真】Unity3D中实现对大疆无人机遥控器手柄按键响应

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群:398291828大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 最近项目中需要用到大疆无人机遥控器对程序中无人机进行控制,遥控器是下图这一款: 博主发…

【案例】根据商品的颜色进行分组,同一种颜色的商品可以对应多种尺寸、价格以及库存

效果展示 效果说明 输入商品的颜色、尺寸后点击添加按钮&#xff0c;即可将对应的商品信息添加到下方的表格当中&#xff0c;表格中除了会显示商品的颜色和尺寸之外&#xff0c;还会显示商品的价格和库存&#xff0c;并且可以对商品的价格和库存进行修改&#xff0c;并且根据颜…

实现mysql的主从复制、实现MySQL的读写分离与负载均衡

实验环境 &#xff08;注明&#xff09;以下的所有关于yum和rpm以及tar的软件需要自己准备&#xff0c;没有的话可以私信博主 实验目标&#xff1a; 1.实现mysql主从复制 2.实现mysql读写分离与负载均衡 实验一、搭建mysql主从复制 1.建立时间同步环境&#xff0c;在主节…

圆上点云随机生成(人工制作模拟数据)

1、背景介绍 实际上,很多地物外表形状满足一定的几何形状结构,如圆形是作为常见一类。那么获取该类目标的点云数据便是位于一个圆上的点云数据。如下图所示为两簇典型的点云,其中一种为理想型,点均位于一个圆上,另外一簇则是近似位于一个圆上,这种更加符合真实情况。有时…