【算法与数据结构】450、LeetCode删除二叉搜索树中的节点

文章目录

  • 一、题目
  • 二、解法
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

在这里插入图片描述
在这里插入图片描述

二、解法

  思路分析:本题首先要分析删除节点的五种情况:

  • 1、没有找到节点
  • 2、找到节点
    • 左右子树为空
    • 左子树为空,右子树不为空
    • 右子树为空,左子树不为空
    • 左右子树均不为空
        程序当中我们选择递归法解题,终止条件中返回一个节点,令上一层递归接住。没有找到节点说明树中没有对应节点的键值,应该是找到空节点的情况。左右子树均为空,说明是叶子节点,返回空节点,并释放空间,上一层中该节点就被置为空节点。左子树不为空,右子树为空,返回左子树即可,反之亦然。左右子树均为不为空的情况比较复杂,因为上一层只接收一个删除后的根节点值,为了使删除后的二叉树仍为二叉搜索树,需要将左右子树合并成一个新的二叉搜索树。那么我们只需将目标节点左子树补位到右子树最底层最左边的节点上,右子树最底层最左边的节点实际上是右子树中键值最小的节点(这个大家可以自己画一个二叉搜索树看看),左子树的值都比这个节点的键值还小,因此需要补位到这个节点的左孩子位置上,伪代码如下,程序当中使用一个while循环寻找右孩子最底层最左边的节点:
	右孩子最底层最左边的节点->left = root->left;auto retNode = root->right;delete root;return retNode;

  程序如下

class Solution {
public:TreeNode* deleteNode(TreeNode* root, int key) {if (root == NULL) return root;  // 没找到节点if (root->val == key) {         // 找到节点if (root->right == NULL && root->left == NULL) {    // 左右孩子均为空,返回空节点delete root;return NULL; }else if (root->left == NULL) {  // 左孩子为空,右孩子不为空,返回右孩子auto retNode = root->right;delete root;return retNode; }else if (root->right == NULL) { // 右孩子为空,左孩子不为空,返回左孩子auto retNode = root->left;delete root;return retNode;  }else {  // 左右孩子均不为空,左孩子补位到右孩子最底层最左边的节点上  TreeNode* cur = root->right;while (cur->left != NULL) {cur = cur->left;}cur->left = root->left;auto retNode = root->right;delete root;return retNode;}            }if (root->val > key) root->left = deleteNode(root->left, key);if (root->val < key) root->right = deleteNode(root->right, key);return root;}
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n),最差情况下,寻找和删除个需要遍历一次树。
  • 空间复杂度: O ( n ) O(n) O(n),递归的深度最深为 O ( n ) O(n) O(n)

三、完整代码

# include <iostream>
# include <vector>
# include <string>
# include <queue>
using namespace std;// 树节点定义
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* deleteNode(TreeNode* root, int key) {if (root == NULL) return root;  // 没找到节点if (root->val == key) {         // 找到节点if (root->right == NULL && root->left == NULL) {    // 左右孩子均为空,返回空节点delete root;return NULL; }else if (root->left == NULL) {  // 左孩子为空,右孩子不为空,返回右孩子auto retNode = root->right;delete root;return retNode; }else if (root->right == NULL) { // 右孩子为空,左孩子不为空,返回左孩子auto retNode = root->left;delete root;return retNode;  }else {  // 左右孩子均不为空,左孩子补位到右孩子最底层最左边的节点上  TreeNode* cur = root->right;while (cur->left != NULL) {cur = cur->left;}cur->left = root->left;auto retNode = root->right;delete root;return retNode;}            }if (root->val > key) root->left = deleteNode(root->left, key);if (root->val < key) root->right = deleteNode(root->right, key);return root;}
};// 前序遍历迭代法创建二叉树,每次迭代将容器首元素弹出(弹出代码还可以再优化)
void Tree_Generator(vector<string>& t, TreeNode*& node) {if (!t.size() || t[0] == "NULL") return;    // 退出条件else {node = new TreeNode(stoi(t[0].c_str()));    // 中if (t.size()) {t.assign(t.begin() + 1, t.end());Tree_Generator(t, node->left);              // 左}if (t.size()) {t.assign(t.begin() + 1, t.end());Tree_Generator(t, node->right);             // 右}}
}template<typename T>
void my_print(T& v, const string msg)
{cout << msg << endl;for (class T::iterator it = v.begin(); it != v.end(); it++) {cout << *it << ' ';}cout << endl;
}template<class T1, class T2>
void my_print2(T1& v, const string str) {cout << str << endl;for (class T1::iterator vit = v.begin(); vit < v.end(); ++vit) {for (class T2::iterator it = (*vit).begin(); it < (*vit).end(); ++it) {cout << *it << ' ';}cout << endl;}
}// 层序遍历
vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> que;if (root != NULL) que.push(root);vector<vector<int>> result;while (!que.empty()) {int size = que.size();  // size必须固定, que.size()是不断变化的vector<int> vec;for (int i = 0; i < size; ++i) {TreeNode* node = que.front();que.pop();vec.push_back(node->val);if (node->left) que.push(node->left);if (node->right) que.push(node->right);}result.push_back(vec);}return result;
}int main()
{// 构建二叉树vector<string> t = { "5", "3", "2", "NULL", "NULL", "4", "NULL", "NULL", "6", "NULL", "7", "NULL", "NULL" };   // 前序遍历my_print(t, "目标树");TreeNode* root = new TreeNode();Tree_Generator(t, root);vector<vector<int>> tree = levelOrder(root);my_print2<vector<vector<int>>, vector<int>>(tree, "目标树:");// 删除目标值int key = 5;Solution s;TreeNode* result = s.deleteNode(root, key);vector<vector<int>> tree1 = levelOrder(result);my_print2<vector<vector<int>>, vector<int>>(tree1, "目标树:");system("pause");return 0;
}

end

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

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

相关文章

微信小程序项目开发Day1

没接触过&#xff0c;直接看视频学习&#xff1a; 千锋教育微信小程序开发制作前端教程&#xff0c;零基础轻松入门玩转微信小程序_哔哩哔哩_bilibili千锋教育微信小程序开发制作前端教程&#xff0c;零基础轻松入门玩转微信小程序共计56条视频&#xff0c;包括&#xff1a;学…

软件工程课件

软件工程 考点概述软件工程概述能力成度模型能力成熟度模型集成软件过程模型逆向工程软件需求需求获取数据流图 需求定义 考点概述 重点章节 软件工程概述 之前老版教程的&#xff0c;之前考过 能力成度模型 记忆 能力等级 和 特点 能力成熟度模型集成 相比于CMM&#xff0c;第…

结合el-input、el-select实现纯前端过滤树形el-table数据

样式图示 1.搜索实现方法 const searchBtn async () > {// 获取table列表数据接口const res await Api.menuList({paging: false})if (res.code 200) {// 把树形结构转成扁平结构let result treeToArray(res.data)// 处理搜索框中数据进行table显示项过滤if(commonData…

分享!JetBrains IDE中的GitLab支持

GitLab是流行的基于git的软件开发和部署平台之一&#xff0c;虽然很长一段时间以来&#xff0c;所有基本git操作都已经可以通过GitLab实现&#xff0c;但GitLab集成仍是JetBrains社区的一大最热门请求。为此&#xff0c;JetBrains团队今年与GitLab联手提供了这种类型的集成。 …

2023年华为杯研究生数学建模竞赛辅导

2023年华为杯研究生数学建模竞赛辅导 各研究生培养单位&#xff1a; 中国研究生数学建模竞赛作为教育部学位管理与研究生教育司指导&#xff0c;中国学位与研究生教育学会、中国科协青少年科技中心主办的“中国研究生创新实践系列大赛”主题赛事之一&#xff0c;是一项面向在校…

使用阿里PAI DSW部署Stable Diffusion WebUI

进入到网址https://pai.console.aliyun.com/里边。 点击创建实例。 把实例名称填写好&#xff0c;选择GPU规格&#xff0c;然后选择实例名称是ecs.gn6v-c8g1.2xlarge。 选择stable-diffusion-webui-env:pytorch1.13-gpu-py310-cu117-ubuntu22.04&#xff0c;然后点击下一步。…

如何利用软文推广进行SEO优化(打造优质软文,提升网站排名)

在当今的互联网时代&#xff0c;SEO优化成为了网站推广的关键。而软文推广作为一种有效的推广方式&#xff0c;其优点不仅仅局限于SEO&#xff0c;还可以带来更多的曝光和用户流量。本文将深入探讨如何做好软文推广&#xff0c;从而提升网站排名和流量。 了解目标受众群体 内容…

springboot集成excel导入导出

1、引入依赖 <dependency><groupId>com.pig4cloud.excel</groupId><artifactId>excel-spring-boot-starter</artifactId><version>1.2.7</version> </dependency> 2、导出 ResponseExcel(name "测试列表") Post…

ORB-SLAM2_RGBD_DENSE_MAP编译、问题解决、离线加载TUM数据和在线加载D435i相机数据生成稠密地图

文章目录 0 引言1 安装依赖1.1 其他库安装1.2 pcl库安装 2 编译ORB-SLAM2_RGBD_DENSE_MAP2.1 build.sh2.2 build_ros.sh 3 运行ORB-SLAM2_RGBD_DENSE_MAP3.1 build.sh编译版本3.2 build_ros.sh编译版本 0 引言 ORB-SLAM2_RGBD_DENSE_MAP是基于ORB-SLAM2框架的一种RGB-D稠密地图…

【视频】Python用LSTM长短期记忆神经网络对不稳定降雨量时间序列进行预测分析|数据分享...

全文下载链接&#xff1a;http://tecdat.cn/?p23544 在本文中&#xff0c;长短期记忆网络——通常称为“LSTM”——是一种特殊的RNN递归神经网络&#xff0c;能够学习长期依赖关系&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 本文使用降雨量数据&#xf…

基于FPGA的图像sobel锐化实现,包括tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 将FPGA的仿真结果导入到matlab显示图像效果 2.算法运行软件版本 MATLAB2022a,vivado2019.2 3.部分核心程序 .................................…

EMANE中olsrd的调试

1 调试目的 本着学习的态度&#xff0c;对emane tutorial中的示例程序进行重现&#xff0c;以加深对EMANE的理解和掌握。在示例程序0(见https://github.com/adjacentlink/emane-tutorial/wiki/Demonstration-0)中介绍了使用olsrlinkview.py脚本来通过可视化界面观察olsr节点的链…

基于Python的UG二次开发入门

文章目录 基于Python的UG二次开发入门1 二次开发环境搭建1.1 安装UG1.2 安装Pycharm1.3 环境配置1.4 测试 2 NX Open介绍2.1 基础架构2.1.1 Sessions and Parts2.1.2 Objects and Tags2.1.3 Factory Objects&#xff08;工厂对象&#xff09;2.1.4 Builder Objects&#xff08;…

9.14号作业

仿照vector手动实现自己的myVector&#xff0c;最主要实现二倍扩容功能 有些功能&#xff0c;不会 #include <iostream>using namespace std; //创建vector类 class Vector { private:int *data;int size;int capacity; public://无参构造Vector(){}//拷贝构造Vector(c…

【绝㊙️】三年开发内功心得

经典嵌套if-else问题 这个也是老生常谈问题了&#xff0c;不管哪里都能看到。 那如何解决 方法一&#xff08;重要&#xff09;&#xff1a; 如果逻辑分支过多&#xff0c; 即使你不解决嵌套if-slse&#xff0c;至少也要把每个 if的{}里的逻辑抽到一个独立的方法或者工具类…

微信小程序的疫苗接种预约设计与实现vue+uniapp

对于本小程序的疫苗预约的设计来说&#xff0c;系统开发主要是采用java语言&#xff0c;在整个系统的设计中应用MySql数据库来完成数据存储&#xff0c;具体根据疫苗预约信息的现状来进行开发的&#xff0c;具体根据现实的需求来实现疫苗预约网络化的管理&#xff0c;各类信息有…

uniapp中video播放视频上按钮没显示的问题

video标签层级很高&#xff0c;尝试了添加z-index&#xff0c;但无效果 通过查阅资料&#xff0c;得知cover-view层级比video层级高 效果图 需求是为了使直播时&#xff0c;可选是原画/流畅 解决方案 首先&#xff0c;在pages.json中配置右上角的图标 {"path" : …

YOLOv5:修改backbone为ConvNeXt

YOLOv5&#xff1a;修改backbone为ConvNeXt 前言前提条件相关介绍ConvNeXtYOLOv5修改backbone为ConvNeXt修改common.py修改yolo.py修改yolov5.yaml配置 参考 前言 记录在YOLOv5修改backbone操作&#xff0c;方便自己查阅。由于本人水平有限&#xff0c;难免出现错漏&#xff0c…

TCP/IP传输协议学习

了解完整的通信过程 1.发送方源终端设备的应用创建数据。 2.当数据在源终端设备中沿协议栈向下传递&#xff0c;对其分段和封装。 3.在协议栈网络接入层的介质上生成数据。 4.通过由介质和任意中间设备组成的网际层网络传输数据。 5.在目的终端设备中沿协议栈向上传递时对其…

微信小程序线上加载使用iconfont问题

1.在微信小程序根目录下创建style文件夹&#xff0c;里面再创建iconfont文件夹&#xff0c;用于放置iconfont图标文件和iconfont样式文件 2.给iconfont.wxss写样式&#xff08;也可以下载iconfont代码&#xff0c;拷贝iconfont.css里的代码复制进去&#xff09; font-face {fo…