【算法】二叉搜索树的插入、删除、转换操作

1 二叉搜索树的插入操作

给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。

示例 1:

输入:root = [4,2,7,1,3], val = 5
输出:[4,2,7,1,3,5]
解释:另一个满足题目要求可以通过的树是:

示例 2:

输入:root = [40,20,60,10,30,50,70], val = 25
输出:[40,20,60,10,30,50,70,null,null,25]

示例 3:

输入:root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
输出:[4,2,7,1,3,5]

法1:递归

插入的数据比当前节点数据小,向左子树递归;

插入的数据比当前节点数据大,向右子树递归。

/*** 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* insertIntoBST(TreeNode* root, int val) {// 空节点if (root == nullptr) {return new TreeNode(val);}if (root->val > val) {root->left = insertIntoBST(root->left, val);}if (root->val < val) {root->right = insertIntoBST(root->right, val);}return root;}
};

法2:迭代

记录遍历的前一个节点,遍历到叶子节点,此时:

如果前一个节点大于当前节点,则将插入数据放到前一个节点的左子树上;

如果前一个节点小于当前节点,则将插入数据放到前一个节点的右子树上;再分别递归左右子树

/*** 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* preNode = nullptr;void helper(TreeNode* root, int val) {// 遍历到叶子节点上if (root == nullptr) {TreeNode* node = new TreeNode(val);// 插到左子树上if (preNode->val > val) {preNode->left = node;} else if (preNode->val < val) {preNode->right = node;}return;}// 更新前一个节点preNode = root;// 左右递归if (root->val > val) {helper(root->left, val);}if (root->val < val) {helper(root->right, val);}}TreeNode* insertIntoBST(TreeNode* root, int val) {if (root == nullptr) {return new TreeNode(val);}helper(root, val);return root;}
};

2 二叉搜索树的删除操作

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

  1. 首先找到需要删除的节点;
  2. 如果找到了,删除它。

示例 1:

输入:root = [5,3,6,2,4,null,7], key = 3
输出:[5,4,6,2,null,null,7]
解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。
另一个正确答案是 [5,2,6,null,4,null,7]。

示例 2:

输入: root = [5,3,6,2,4,null,7], key = 0
输出: [5,3,6,2,4,null,7]
解释: 二叉树不包含值为 0 的节点

示例 3:

输入: root = [], key = 0
输出: []

情况1:该节点为空,直接返回nullptr;

情况2:要删除的是叶子节点,即没有左右子树,直接删除即可;

情况3:要删除的节点有左子树,删除该节点,左子树补位;

情况4:要删除的节点有右子树,删除该节点,右子树补位;

情况5:要删除的节点左右子树都有,将该节点的左子树查到该节点右子树的最左子树,删除该节点。

代码

/*** 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* deleteNode(TreeNode* root, int key) {if (root == nullptr) {return nullptr;}if (root->val == key) {if (root->left == nullptr && root->right == nullptr) {delete root;return nullptr;} else if (root->left != nullptr && root->right == nullptr) {TreeNode* node = root;root = root->left;delete node;return root;} else if (root->left == nullptr && root->right != nullptr) {TreeNode* node = root;root = root->right;delete node;return root;} else if (root->left != nullptr && root->right != nullptr) {// 情况5:要删除的节点左右子树都有,将该节点的左子树查到该节点右子树的最左子树,删除该节点。TreeNode* curNode = root->right;while (curNode->left != nullptr) {curNode = curNode->left;}curNode->left = root->left;TreeNode* node = root;root = root->right;delete node;return root;}}if (root->val > key) {root->left = deleteNode(root->left, key);}if (root->val < key) {root->right = deleteNode(root->right, key);}return root;}
};

3 二叉搜索树的转换操作

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

示例 1:

输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:

示例 2:

输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。

直接递归

/*** 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* helper(vector<int>& nums, int i, int j) {if (i > j) {return nullptr;}int mid = i + (j - i) / 2;TreeNode* root = new TreeNode(nums[mid]);root->left = helper(nums, i, mid - 1);root->right = helper(nums, mid + 1, j);return root;}TreeNode* sortedArrayToBST(vector<int>& nums) {return helper(nums, 0, nums.size() - 1);}
};

链接:

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

[2] . - 力扣(LeetCode)

[3] . - 力扣(LeetCode)

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

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

相关文章

小程序原生 API

微信原生 API 1. API 基础 小程序开发框架提供丰富的微信原生 API&#xff0c;可以方便的调起微信提供的能力&#xff0c;如获取用户信息&#xff0c;本地存储&#xff0c;支付功能等&#xff0c;几乎所有小程序的 API 都挂载在 wx 对象底下&#xff0c;例如&#xff1a;wx.c…

#LLM入门|Prompt#2.2_ AI 应用开发的范式_Language_Models,the_Chat_Format_and_Tokens

在本章中&#xff0c;我们将和您分享大型语言模型&#xff08;LLM&#xff09;的工作原理、训练方式以及分词器&#xff08;tokenizer&#xff09;等细节对 LLM 输出的影响。 我们还将介绍 LLM 的提问范式&#xff08;chat format&#xff09;&#xff0c;这是一种指定系统消息…

STM32合并烧录IAP+APP

STM32合并烧录IAPAPP 通过查找相关资料 有以下几种合并方法 第一种直接将二进制文件用记事本合并 而要合并的就是就将IAP最后的一行删除&#xff0c;然后将APP程序追加在后面。 &#xff08;修改前&#xff09; 把APP的.hex 全部内容拷贝复制到 刚才删掉结束语句的 IAP的.…

Win32汇编ListView控件学习

此控件比较复杂&#xff1b;和基础win32控件不同&#xff1b;需要先初始化Windows公共控件库&#xff0c; invoke InitCommonControls 之后才可使用&#xff1b; lvdemo.asm&#xff0c; .386.model flat, stdcalloption casemap :none ; case sensitiveinclude window…

【OCR识别】使用OCR技术还原加密字体文字

文章目录 1. 写在前面2. 页面分析3. 字符知识4. 加密分析 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感兴趣的朋…

减少页面加载时间:提升用户体验的关键

✨✨ 祝屏幕前的您天天开心&#xff0c;每天都有好运相伴。我们一起加油&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 一、为什么页面加载时间重要&#xff1f; 二、如何减少页面加载时间&#xff1f; …

华润置地品牌虚拟代言人IP“吉吉”,开启地产数字化营销新场景

在数字化营销时代&#xff0c;房地产品牌通过虚拟人技术&#xff0c;可以有效链接购房者&#xff0c;占领客户心智&#xff0c;优化购房体验&#xff0c;塑造年轻化、数字化的品牌形象。 华润置地积极拥抱数字变革&#xff0c;通过广州虚拟动力「现场虚拟主持技术服务」与「虚…

【Unity】使用Unity实现双屏显示

引言 在使用Unity的时候&#xff0c;有时候会需要使用双屏显示 简单来说就是需要在两个显示器中显示游戏画面 双屏显示注意点&#xff1a; ①双屏显示需要电脑有两个显示 ②双屏显示只能用于PC端 ③不仅仅可以双屏&#xff0c;Unity最大支持8屏显示 1.相机设置 ①我们打开Un…

Untiy webgl iis服务器加载ab包报404.3,需要为AB包添加MIMI映射

首选确定一下文件在不在 这里是缺少对于AB包文件类型的映射&#xff0c;因为AB包没有后缀名&#xff0c;我们为服务器添加通用的映射 1 开始菜单搜索iis管理器,先选中我们的服务器&#xff0c;然后双击进入MIME类型 2 右侧点击添加按钮 3 添加如下内容 文件扩展名为. 类型为…

性能测试-并发测试心得

一些关键名词 吞吐量 指的是在一定时间内系统处理请求或传输数据的能力&#xff0c;具体到性能测试中的话&#xff0c;就是指单位时间内系统处理并完成的请求数量或者是系统传输的数据量。 例如&#xff0c;吞吐量可以表示为系统每秒处理HTTP请求次数&#xff0c;或者是系统…

服务器git安装python包失败,如何手动下载github项目包并安装到虚拟环境中(简单易懂)

背景&#xff1a; 想要复现一个项目&#xff0c;建立好虚拟环境后&#xff0c;准备安装项目需要的包&#xff0c;故输入命令pip install -r requirements.txt requirements.txt如下图 其他包我都安装成功了&#xff0c;只有最后一个包失败了&#xff0c;是需要服务器git链接…

【学习心得】解决无限debugger的常用方法

一、什么是无限debugger 有些网站为了防止爬虫或其他恶意行为&#xff0c;会故意设置无限debugger作为一种简单的反爬机制&#xff0c;它会在开发者工具打开的情况下不断暂停执行。这对于想要分析其他代码逻辑、排查问题或进行正常开发调试工作的开发者来说极为不便。 二、解决…

Sora学习笔记

Sora - 探索AI视频模型的无限可能 随着人工智能技术的飞速发展&#xff0c;AI视频模型已成为科技领域的新热点。而在这个浪潮中&#xff0c;OpenAI推出的首个AI视频模型Sora&#xff0c;以其卓越的性能和前瞻性的技术&#xff0c;引领着AI视频领域的创新发展。让我们将一起探讨…

ios 使用window.location.href 不能跳转微信短链处理过程以及解决方法

需求背景&#xff1a; 由h5提供页面&#xff0c;通过后台请求微信api生成对应的schemal短链&#xff0c;该h5页面嵌入到原生的ios以及安卓app上&#xff0c;当用户点击后通过短连接跳转到其他小程序中 以下为生成微信scheme代码示例&#xff0c;生成后短链为&#xff1a;weixi…

Azure[Sky] Dynamic Skybox

Azure[Sky] Dynamic Skybox是一个完整而稳健的天空系统,它可将你的项目提升大到其他层次。 Azure[Sky] 不仅适合使用现实图片的项目,事实上,该系统用在风格化图片的项目也很不粗,甚至效果更好。使用 Azure,每种风格都能实现最佳效果。 性能: 在开发此资源的过程中,性能是…

【Android】属性动画

在属性动画出现之前&#xff0c;Android 系统提供的动画只有帧动画和 View 动画。View 动画我们都了解&#xff0c;它提供了 AlphaAnimation、RotateAnimation、TranslateAnimation、ScaleAnimation 这4种动画方式&#xff0c;并提供了 AnimationSet 动画集合来混合使用多种动画…

35. 【Linux教程】Linux 修改用户组

前面小节介绍了如何添加用户组&#xff0c;本小节介绍如何给已经添加的新用户组修改信息&#xff0c;从 /etc/group 文件信息可以看到&#xff0c;用户组的信息比用户信息项少&#xff0c;和 usermod 命令类似&#xff0c;用户组的信息可以使用 groupmod 命令修改。 1. groupmo…

为了董宇辉,老婆跟我打起来了!写下一份深刻检讨

两个月前&#xff0c;因为讨论董宇辉小作文事件&#xff0c;跟老婆吵起来了。起因就为了两句话&#xff0c;写了这份检讨&#xff01;给大家分享一下。 老婆在网上刷了两晚关于董宇辉小作文的视频&#xff0c;一直为董宇辉喊冤、打抱不平。起初&#xff0c;我跟老婆的想法&…

怎样消除视频上的字幕和文字?3个方法值得推荐

怎样消除视频上的字幕和文字&#xff1f;消除视频上的字幕和文字不仅是一个常见的需求&#xff0c;更是一个对视频内容质量提升的关键步骤。特别是在处理从网络下载的带有水印或标识的视频时&#xff0c;这些额外的文字和信息往往会干扰观众的观看体验&#xff0c;甚至可能影响…

【数据结构】顺序表和链表的对比,在各种情况下如何选择

顺序表详细内容&#xff1a; 【数据结构】线性表 顺序表&#xff08;动态、静态分配&#xff0c;插入删除查找基本操作&#xff09;解析完整代码 单链表详细内容&#xff1a; 【数据结构】单链表解析完整代码&#xff08;插入、删除、尾插法、头插法、按值和按位查找、前插和后…