Day 25 二叉树的终止

news2024/9/20 5:01:22

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

不理解用tmp保存root节点,然后删除?root=root->right不会覆盖吗?

需要考虑要删除的节点是不是叶子节点,有无左右孩子

有左右孩子的话,需要将左孩子节点移动到右孩子节点的左面节点的左孩子上。

669. 修剪二叉搜索树

但是有返回值,更方便,可以通过递归函数的返回值来移除节点,大概解释下:

  1. 定义一个递归函数,它接受一个节点作为参数,并尝试在该节点及其子树中找到要移除的节点。
  2. 如果当前节点就是要移除的节点,返回该节点,并在适当的情况下更新其父节点的引用以跳过这个被移除的节点。
  3. 如果当前节点不是要移除的节点,递归地在左子树和右子树中查找并移除节点。
  4. 如果在左子树或右子树中找到了要移除的节点,更新当前节点的子节点引用以跳过被移除的节点。

迭代法是一种通过循环来重复执行某段代码直到满足某个条件为止的方法。在迭代过程中,通常使用循环结构(如whilefor循环)来控制代码的执行次数。迭代法不需要额外的函数调用栈空间,因为它直接在当前的函数栈帧中完成所有操作。

在剪枝二叉搜索树时,迭代法可以通过维护一个指针(如cur)来遍历树的节点,并根据需要更新指针的指向。这种方法不需要递归调用,因此可以避免额外的函数调用开销和栈空间使用。

1. 如果根节点为空,那么直接返回nullptr。 if (!root) return nullptr;
2. 移动根节点到[L, R]范围内:

while (root != nullptr && (root->val < L || root->val > R)) {  
    if (root->val < L) root = root->right; // 小于L往右走  
    else root = root->left; // 大于R往左走  
}


这段代码的目的是确保root节点位于[L, R]的范围内。如果root的值小于L,那么它会移动到root的右子树中;如果root的值大于R,那么它会移动到root的左子树中。
3. 处理左子树中小于L的节点:
TreeNode *cur = root;  
// 此时root已经在[L, R] 范围内,处理左孩子元素小于L的情况  

while (cur != nullptr) {  
    while (cur->left && cur->left->val < L) {  
        cur->left = cur->left->right;  
    }  
    cur = cur->left;  
}

从root开始,遍历左子树,并删除所有值小于L的节点。这是通过将其父节点的左指针指向其右子节点来实现的。
4. 重置cur并处理右子树中大于R的节点:

cur = root;  
// 此时root已经在[L, R] 范围内,处理右孩子大于R的情况  
while (cur != nullptr) {  
    while (cur->right && cur->right->val > R) {  
        cur->right = cur->right->left;  
    }  
    cur = cur->right;  
}

然后,再次从root开始,遍历右子树,并删除所有值大于R的节点。这是通过将其父节点的右指针指向其左子节点来实现的。
5. 返回修剪后的根节点:
return root;
最后,返回修剪后的树的根节点。

递归逻辑

  1. 如果root->val < low
    • 这种情况下,当前节点root及其左子树中的所有节点都应该被删除,因为它们都小于low
    • 我们递归地调用trimBST来处理root的右子树,并返回修剪后的右子树的根节点作为新的root
  2. 如果root->val > high
    • 这种情况下,当前节点root及其右子树中的所有节点都应该被删除,因为它们都大于high
    • 我们递归地调用trimBST来处理root的左子树,并返回修剪后的左子树的根节点作为新的root
  3. 如果low <= root->val <= high
    • 这种情况下,当前节点root的值在允许的范围内,所以我们需要保留它。
    • 我们递归地调用trimBST来处理root的左子树和右子树,并将修剪后的左子树的根节点赋值给root->left,将修剪后的右子树的根节点赋值给root->right
    • 最后返回root,因为它现在是修剪后的子树的根节点。

关键点

  • 由于BST的特性(父节点的值大于左子树中所有节点的值,小于右子树中所有节点的值),我们可以直接根据当前节点的值与lowhigh的比较结果来决定是否保留该节点以及是否继续递归处理其子树。
  • 递归是处理树形结构的有效方法,它可以将复杂的问题分解为更小的子问题来解决。在这个问题中,递归地修剪左子树和右子树是保持BST性质的关键。
  • 函数的返回值是修剪后的子树的根节点,这允许我们在递归调用中构建并返回修剪后的树。

108.将有序数组转换为二叉搜索树

核心在于利用了二叉搜索树(BST)的特性以及二分查找(Binary Search)的思想来迭代地将一个有序数组转化为一个BST。

首先,让我们分析这段代码:

  1. traversal 函数是一个私有辅助函数,它接受一个有序数组 nums、一个左索引 left 和一个右索引 right 作为参数。这三个参数定义了一个子数组的范围,该函数的任务是根据这个子数组的范围来构建BST的一个子树。

  2. 如果 left > right,说明子数组为空(或只有一个元素但已经被前面的递归处理了),那么返回 nullptr,表示没有节点需要创建。

  3. 否则,找到子数组的中间元素 mid,这个元素将成为当前BST子树的根节点。这利用了BST的特性:根节点的值总是大于左子树的所有值,小于右子树的所有值。

  4. 递归地调用 traversal 函数来构建左子树(使用 left 到 mid - 1 的索引范围)和右子树(使用 mid + 1 到 right 的索引范围)。这是二分查找的关键步骤,它将原始问题(构建整个BST)分解为两个更小的问题(构建左子树和右子树)。

  5. 最后,将左子树和右子树连接到根节点,并返回根节点。

  6. sortedArrayToBST 函数是公开的,它接受一个有序数组 nums 并调用 traversal 函数来构建BST的根节点。这个根节点是整个BST的入口点。

class Solution {
private:
    TreeNode* traversal(vector<int>& nums, int left, int right) {
        if (left > right) return nullptr;
        int mid = left + ((right - left) / 2);
        TreeNode* root = new TreeNode(nums[mid]);
        root->left = traversal(nums, left, mid - 1);
        root->right = traversal(nums, mid + 1, right);
        return root;
    }
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        TreeNode* root = traversal(nums, 0, nums.size() - 1);
        return root;
    }
};

538.把二叉搜索树转换为累加树

将二叉搜索树(BST)转换为一个累加树(Greater Sum Tree),其中每个节点的新值是该节点原始值及其所有后续节点(在中序遍历中的顺序)原始值的和。由于BST的特性(左子节点值小于父节点,右子节点值大于父节点),我们可以通过反中序遍历(右-根-左)来实现这个转换。

在反中序遍历中,我们从BST的最大值开始(即最右边的节点),然后向上遍历到根节点,并继续向左遍历,这样我们就能确保在遍历到每个节点时,我们已经计算出了所有后续节点的和。

1. 不需要递归函数的返回值做什么操作了,要遍历整棵树。

2. 遇空就终止。

3. 于当前访问的节点cur,我们将其值更新为cur.val + pre.val(如果pre是节点)或cur.val + pre(如果pre是整数值)。然后,我们更新pre为当前节点cur(如果pre是节点)或cur.val(如果pre是整数值)。

class Solution {  
private:  
    // 私有成员变量pre,用于记录前一个节点的累加值(初始化为0)  
    int pre = 0; // 记录前一个节点的数值  
  
    // 定义一个私有函数traversal,用于执行反中序遍历(右-根-左)并更新节点值  
    void traversal(TreeNode* cur) { // 右中左遍历  
        // 如果当前节点为空,则返回(结束递归)  
        if (cur == NULL) return;  
  
        // 先遍历右子树  
        traversal(cur->right);  
  
        // 更新当前节点的值为原值加上前一个节点的累加值  
        cur->val += pre;  
  
        // 更新pre为当前节点的值(包括累加值),以便后续节点使用  
        pre = cur->val;  
  
        // 再遍历左子树  
        traversal(cur->left);  
    }  
  
public:  
    // 公开成员函数convertBST,接收一个二叉搜索树的根节点作为参数  
    // 执行反中序遍历并更新节点值,然后返回根节点(此时根节点已经是累加树的根节点)  
    TreeNode* convertBST(TreeNode* root) {  
        // 初始化pre为0  
        pre = 0;  
  
        // 执行反中序遍历并更新节点值  
        traversal(root);  
  
        // 返回转换后的累加树的根节点  
        return root;  
    }  
};

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

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

相关文章

Python | Leetcode Python题解之第142题环形链表II

题目&#xff1a; 题解&#xff1a; # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val x # self.next Noneclass Solution(object):def detectCycle(self, head):""":type head: ListNode:…

element-plus 的el-scrollbar滚动条组件

el-scrollbar组件可以替换原生的滚动条&#xff0c;可以设置出现滚动条的高度&#xff0c;若无设置则根据容器自适应。 通过使用 setScrollTop 与 setScrollLeft 方法&#xff0c;可以手动控制滚动条滚动。 scroll 滚动条的滚动事件&#xff0c;会返回滚动条当前的位置。 &l…

机器学习--生成式模型和判别式模型的具体分析

文章目录 生成式模型和判别式模型的具体分析生成式模型定义工作原理优点缺点常见模型 判别式模型 总结生成式模型判别式模型 生成式模型和判别式模型的具体分析 生成式模型和判别式模型在机器学习中有着不同的目标、应用场景和性能特点。以下将详细分析它们的定义、工作原理、…

《庆余年》角色穿越高考:谁将笑傲现代考场?

一、引言 《庆余年》是一部以古代中国为背景的权谋小说&#xff0c;其角色们各具特色&#xff0c;聪明才智、武艺高强、忠诚耿直等特质使得他们在古代世界中游刃有余。然而&#xff0c;如果我们将这些角色置于现代高考的背景之下&#xff0c;他们将如何面对这一挑战&#xff1…

C# WPF入门学习主线篇(二十)—— 资源和样式

C# WPF入门学习主线篇&#xff08;二十&#xff09;—— 资源和样式 欢迎来到C# WPF入门学习系列的第二十篇。在前面的章节中&#xff0c;我们探讨了布局管理及各种控件的使用。本篇博客将重点介绍WPF中的资源&#xff08;Resource&#xff09;和样式&#xff08;Style&#xf…

抛弃昂贵BI,企业仍可低成本实现数据分析

有的读者看完《BI工具选型不入坑&#xff0c;你要这么选》这篇文章就陷入迷茫了&#xff0c;我要做企业级数据分析&#xff0c;看过去各家产品都各有千秋&#xff0c;实在难以抉择&#xff0c;或者已经选了仍是纠结不已。 这里我抛出另一种思路&#xff1a;如果不用BI&#xf…

MySQL 5.7详细下载安装配置教程(MySQL 5.7安装包)_mysql5.7的安装教程

记录MySQL 5.7 的下载安装教程&#xff0c;并提供了Mysql 安装包 &#xff0c;以下是详细下载安装过程。 一、下载Mysql安装包 网盘下载&#xff1a; 下载MySQL 5.7安装包&#xff0c;网盘下载地址&#xff1a;点击此处直接下载 官网下载&#xff1a; 进入官网&#xff0c…

如何稳定高效地进行 TiDB 数据导入导出?

对于在数据库行业中摸爬滚打多年的老鸟 DBA 来说&#xff0c;TiDB 可是一点也不陌生&#xff0c;作为 PingCAP 公司自主研发的真开源分布式数据库&#xff0c;其先进的设计理念以及丰富的生态工具&#xff0c;可算得上是业界自主创新和性能领先的代名词。 TiDB 是谁&#xff1…

《Brave New Words 》3.4 最重要的学科领域

Part III Empowering the Next Innovators 第三部分 赋能下一代创新者 The Most Important Subject-Matter Domain to Master 最重要的学科领域 In the world of education, it’s crucial for developers to field-test their ideas. Essentially, it means taking our educat…

LabVIEW进行图像拼接的实现方法与优化

在工业检测和科研应用中&#xff0c;对于大尺寸物体的拍摄需要通过多次拍摄后进行图像拼接。LabVIEW 作为强大的图形化编程工具&#xff0c;能够实现图像拼接处理。本文将详细介绍LabVIEW进行图像拼接的实现方法、注意事项和提高效率的策略。 图像拼接的实现方法 1. 图像采集…

前端UI框架Element Plus 和 Ant Design Vue哪个好

Element Plus 和 Ant Design Vue 都是基于 Vue.js 的 UI 组件库&#xff0c;它们具备一系列可复用的组件和丰富的功能&#xff0c;并且是当前国内主流的两个 UI 组件库。 &#xff08;1&#xff09;Element Plus 是饿了么前端团队推出的开源项目&#xff0c;是对 Element UI 的…

基于Python + Flask+ Mysq实现简易留言板

使用Python Flask Mysql实现简易留言板&#xff0c;包括网友编辑留言、修改留言&#xff0c;删除留言、分页显示四大功能。 写出留言板建设过程&#xff0c;包括开发使用工具、留言板模块设计、数据库设计、页面设计、关键技术。 留言板建设过程总结 一&#xff0e;开发使用…

RapidMiner数据挖掘4 —— 决策树

0. 序章 0.1 文本说明 所有应用程序操作的名称和编程说明都以黄色背景书写&#xff0c;问题以蓝色背景书写&#xff0c;以方便他们在文本中识别。 在整个课程中&#xff0c;请逐步遵循所有说明&#xff0c;并确保获得预期结果&#xff0c;然后再继续下一部分或问题。 通过在Ub…

文刻ai工具跟绘唐AI工具有什么区别

文刻AI工具和绘唐AI工具是两种不同的人工智能工具。点击查看 文刻AI工具是一种自然语言处理工具&#xff0c;可以用于生成、修改和校对文本。它可以帮助用户更高效地写作&#xff0c;提供词汇和语法建议&#xff0c;检查拼写和语法错误&#xff0c;并提供自动补全和自动纠正功…

网络安全难学吗?2024该怎么系统学习网络安全?

学习网络安全需要循序渐进&#xff0c;由浅入深。很多人对网络安全进行了解以后&#xff0c;就打算开始学习网络安全&#xff0c;但是又不知道怎么去系统的学习。 网络安全本身的知识不难&#xff0c;但需要学习的内容有很多&#xff0c;其中包括Linux、数据库、渗透测试、等保…

ue5肉鸽游戏视频教程学习记录

先在虚幻商城下载免费的paperzd插件&#xff0c;并启用。 导入资源后&#xff0c;先通过应用paper2d纹理资源&#xff0c;将去掉导入ue时产生的边缘模糊&#xff0c;再点击下面的创建瓦片集&#xff0c; 打开瓦片集&#xff0c;发现选中不对&#xff0c; 改变瓦片大小为16*…

64. UE5 RPG 创建新的双手攻击怪物

在上一篇文章中&#xff0c;我们实现了新的功能&#xff0c;现在可以创建多个普通攻击动画&#xff0c;并且可以根据你所使用的普通攻击动画&#xff0c;设置不同的攻击位置。比如&#xff0c;你使用武器&#xff0c;那么攻击位置需要从武器上获取&#xff0c;如果你没有持有武…

保存图片奇怪的bug

今天发现一个奇怪的bug 这个的dpi是100de ,但是我取完切片之后&#xff0c;发现这个结果就变了

温度传感器十大品牌

温度传感器品牌排行榜-十大热电偶品牌-热敏电阻品牌排行-Maigoo品牌榜

西门子学习笔记11 - PTO脉冲指令的使用

1、使用指令前的设置 1、打开一个脉冲发生器&#xff0c;并启用 2、选择使用PTO(脉冲A和方向B) 3、硬件设置输出 4、这样前期的准备工作就完成了 2、指令的使用 1、添加指令CTRL_PTO 2、配置如下 3、方向控制程序如下 4、最后进行测试即可