二叉树例题分享

文章目录

  • 二叉树例题分享
      • [235. 二叉搜索树的最近公共祖先](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/)
      • [701. 二叉搜索树中的插入操作](https://leetcode.cn/problems/insert-into-a-binary-search-tree/)
      • [108. 将有序数组转换为二叉搜索树](https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/)
      • [450. 删除二叉搜索树中的节点](https://leetcode.cn/problems/delete-node-in-a-bst/)

二叉树例题分享

235. 二叉搜索树的最近公共祖先

题目

在这里插入图片描述

代码

struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p,
                                      struct TreeNode* q) {
    struct TreeNode* ans = root;
    while (ans != NULL) {
        if (ans->val > p->val && ans->val > q->val) {
            ans = ans->left;
        } else if (ans->val < p->val && ans->val < q->val) {
            ans = ans->right;
        } else {
            return ans;
        }
    }
    return ans;
}

题解

本题要求我们找到二叉搜索树中两个节点的最小公共祖先,因为是二叉搜索树,所以实现起来还是比较简单的,因为二叉搜索树的左子树数值一定小于根节点数值小于右子树数值。

多以我们遍历一遍二叉树就可以找到答案:

  • 如果ans节点数值同时大于p,q数值,那么p,q一定在ans节点的左边,向左遍历;
  • 如果ans节点数值同时小于p,q数值,那么p,q一定在ans节点的右边,向右遍历;
  • 如果一大一小,那证明找到了最近公共祖先。

总体来说只要我们知道在什么情况下是最近公共祖先,我们就可以轻松实现本题要求。

701. 二叉搜索树中的插入操作

题目

在这里插入图片描述

代码

struct TreeNode* insertIntoBST(struct TreeNode* root, int val) {
    struct TreeNode* ans = root;
    struct TreeNode* new = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    new->left = NULL;
    new->right = NULL;
    new->val = val;
    if (root == NULL)
        return new;
    while (root) {
        if (root->val > val) {
            if (root->left != NULL)
                root = root->left;
            else {
                root->left = new;
                return ans;
            }
        } else {
            if (root->right != NULL)
                root = root->right;
            else {
                root->right = new;
                return ans;
            }
        }
    }
    return ans;
}

题解

本题可以使用两种方法去实现:

第一种

​ 迭代法

迭代法是我在没有看题解情况下完成的。

因为是二叉搜索树,所以我们遍历一次便可以实现。

我们在遍历二叉树的时候,如果本节点的数值大于val,则证明val应该插入到左子树中,反之插入右子树中,我们只需要继续判断本节点的左孩子节点(右孩子节点)是否为空,如果不为空则继续遍历,如果为空则证明该位置就为插入位置。

下面是代码:

struct TreeNode* insertIntoBST(struct TreeNode* root, int val) {
    if (root == NULL)
        return root;
    struct TreeNode* ans = root;
    struct TreeNode* new = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    new->left = NULL;
    new->right = NULL;
    new->val = val;
    while (root) {
        if (root->val > val) {
            if (root->left != NULL)
                root = root->left;
            else {
                root->left = new;
                return ans;
            }
        } else {
            if (root->right != NULL)
                root = root->right;
            else {
                root->right = new;
                return ans;
            }
        }
    }
    return ans;
}

第二种

​ 递归法

  • 终止递归是如果遇到了空节点,则证明该位置就应该是插入位置,直接返回新节点接可以了;
  • 后面我们考虑一层递归的逻辑,我们判断val与root->val的大小关系,然后继续遍历左孩子节点或右孩子节点(之后会返回),并且用root->left或root->right接住返回值;
  • 最后返回root就可以了。

最后的代码是这样的:

struct TreeNode* insertIntoBST(struct TreeNode* root, int val) {
    if (root == NULL) {
        struct TreeNode* new =
            (struct TreeNode*)malloc(sizeof(struct TreeNode));
        new->left = NULL;
        new->right = NULL;
        new->val = val;
        return new;
    }
    if (val > root->val)
        root->right = insertIntoBST(root->right, val);
    if (val < root->val)
        root->left = insertIntoBST(root->left, val);
    return root;
}

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

题目

在这里插入图片描述

代码

struct TreeNode* Traval(int* nums, int left, int right) {
    if (left > right)
        return NULL;
    int mid = (left + right) / 2;
    struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    root->val = nums[mid];
    root->left = Traval(nums, left, mid - 1);
    root->right = Traval(nums, mid + 1, right);
    return root;
}

struct TreeNode* sortedArrayToBST(int* nums, int numsSize) {
    return Traval(nums, 0, numsSize - 1);
}

题解

本题要求我们将给定的升序数组转换成一棵平衡二叉搜索树。

我们的思路就是每次都将数组中的中间元素设置成根节点,然后将左边的设置为左子树,右边的设置为右子树,然后对左子树和右子树再进行相同的处理(运用递归)。

下面是代码:

struct TreeNode* Traval(int* nums, int left, int right) {
    if (left > right)
        return NULL;
    int mid = (left + right) / 2;
    struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    root->val = nums[mid];
    root->left = Traval(nums, left, mid - 1);
    root->right = Traval(nums, mid + 1, right);
    return root;
}

struct TreeNode* sortedArrayToBST(int* nums, int numsSize) {
    return Traval(nums, 0, numsSize - 1);
}

这里要说的是上面的终止条件(left>right),这里是因为我们传参是left和mid-1或者mid+1和right,如果left>right就证明节点为空,直接返回空节点就可以了。

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

题目
在这里插入图片描述

代码

struct TreeNode* deleteNode(struct TreeNode* root, int key){
    if(root==NULL)
        return NULL;
    if(root->val==key){
        if(root->left==NULL&&root->right==NULL)
            return NULL;
        else if(root->left==NULL&&root->right!=NULL)
            return root->right;
        else if(root->left!=NULL&&root->right==NULL)
            return root->left;
        else if(root->left!=NULL&&root->right!=NULL){
            struct TreeNode* cur=root->right;
            while(cur->left!=NULL)
                cur=cur->left;
            cur->left=root->left;
            return root->right;
        }
    }
    if(root->val>key)
        root->left=deleteNode(root->left,key);
    if(root->val<key)
        root->right=deleteNode(root->right,key);
    return root;
}

题解

本题我们在删除的地方有五种情况:

  • 第一种情况:没找到删除的节点,遍历到空节点直接返回了
  • 找到删除的节点
    • 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
    • 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
    • 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
    • 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。

如果我们搞清楚了这五种情况,我们运用递归很容易就可以实现这道题。

已经到底啦!!

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

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

相关文章

Pixel 手机上连接提示受阻,无法上网-解决方法

命令行中输入 adb shell settings delete global captive_portal_https_urladb shell settings delete global captive_portal_http_url输入服务器信息 adb shell settings put global captive_portal_http_url http://connect.rom.miui.com/generate_204adb shell settings …

【Canvas与艺术】绘制方形斜纹生化危险Biohazard标志

【关键点】 绘制切角矩形、三角形比较费工&#xff0c;有时间可以把相关代码做成函数。 【成果图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <…

【Golang学习笔记】从零开始搭建一个Web框架(四)

文章目录 模板渲染静态文件支持HTML 模板渲染 错误恢复完结撒花~~ 前情提示&#xff1a; 【Golang学习笔记】从零开始搭建一个Web框架&#xff08;一&#xff09;-CSDN博客 【Golang学习笔记】从零开始搭建一个Web框架&#xff08;二&#xff09;-CSDN博客 【Golang学习笔记】从…

ChatGLM3初体验

mac本地化部署ChatGLM3 写在前面环境准备1. python环境2. 安装第三方依赖torch3.下载模型 代码准备1.clone代码 run效果 写在前面 建议直接去看官方文档 https://github.com/THUDM/ChatGLM3?tabreadme-ov-file 环境准备 1. python环境 python -V ## 3.11.42. 安装第三方依…

怎么提升公众号上限

正常可以申请多少个公众号&#xff1f;目前如果我们是企业主体的话&#xff08;包括个体户&#xff09;&#xff0c;申请公众号默认是可以申请2个公众号数量的。不过对于很多公司来说&#xff0c;2个公众号的数量肯定是远远不够用的&#xff0c;不同的产品不同品牌不同部门都可…

倍增法学习

这里i为开始下标&#xff0c;j是2的次幂

OSPF 开放式最短路径优先协议

目录 技术产生原因&#xff1a;因为RIP存在不足 OSPF优点&#xff1a; RIPV2和OSPFV2比较&#xff1a; 相同点&#xff1a; 不同点&#xff1a; OSPF的结构化部署 --- 区域划分 区域划分的主要目的&#xff1a; 区域边界路由器 --- ABR &#xff1a; 区域划分的要求&am…

医疗图像分割 | 基于Pyramid-Vision-Transformer算法实现医疗息肉分割

项目应用场景 面向医疗图像息肉分割场景&#xff0c;项目采用 Pytorch Pyramid-Vision-Transformer 深度学习算法来实现。 项目效果 项目细节 > 具体参见项目 README.md (1) 模型架构 (2) 项目依赖&#xff0c;包括 python 3.8、pytorch 1.7.1、torchvision 0.8.2(3) 下载…

2024 ICLR Oral 泛读调研(一、关于深度学习训练技术)

调研阅读要求&#xff1a; &#xff08;1&#xff09;先读要点&#xff1a;标题、摘要&#xff0c;随后直接跳到结论。 &#xff08;2&#xff09;实验结果&#xff1a;图、表、伪代码。 &#xff08;3&#xff09;对比角度&#xff1a;实验环境、数据集、测试方法、评估指标、…

嵌入式webrtc音视频多端p2p sfu传输方案

Webrtc在实时音视频中占据重要位置&#xff0c;在小型嵌入式设备上实现音视频数据的组合传输也越来越成为趋势&#xff0c;通过方便快捷的信令调度&#xff0c;可以实时相互拉取对等方的音视频流也可以通过sfu服务器实现转发。 我们在实践中采用物联网常用的mqtt协议来实现设备…

如何发现高危的PoC和EXP?漏洞检测方法 示例,实战应急实战举例,包括:SQLi、XSS、SSTI/ELI、文件哈希、SSRF、命令执行/命令注入等等

如何发现高危的PoC和EXP?漏洞检测方法 & 示例,实战应急实战举例,包括:SQLi、XSS、SSTI/ELI、文件哈希、SSRF、命令执行/命令注入等等。 在网络安全领域,发现高危的PoC(Proof of Concept)和EXP(Exploit)对于防范和应对潜在的安全威胁至关重要。以下是关于如何发现高…

使用Python实现自动化网页答题功能-模拟考试篇

介绍 在驾驶员考试网站上进行模拟考试python自动答题 自动化原理 该脚本使用了自动化模块 DrissionPage 中的 ChromiumPage 类来实现网页的自动化操作。通过定位网页元素和模拟点击操作&#xff0c;完成了选择答案和提交答卷的过程。 用途与注意事项 用途&#xff1a;该脚本…

安卓逆向 | 某X游戏垂类Web nonce

*本案例仅做分析参考,如有侵权请联系删除 1.逻辑分析 通过XHR断点,然后逐步往上调发现nonce生出处。 在console执行下函数 其中 i,是当前日期和时间的秒级时间戳,并将其向下取整到最接近的整数。 i = ~~(+_.w() / 1e3)w</

《剑指 Offer》专项突破版 - 面试题 108 : 单词演变(C++ 实现)

目录 前言 单向广度优先搜索 双向广度优先搜索 前言 题目链接&#xff1a;单词演变 题目&#xff1a; 输入两个长度相同但内容不同的单词&#xff08;beginWord 和 endWord&#xff09;和一个单词列表&#xff08;wordList&#xff09;&#xff0c;求从 beginWord 到 end…

测试计划和测试报告

1、软件测试计划简介 测试计划&#xff0c;一般是主管写&#xff0c;在需求分析之后&#xff0c;测试工作开始之间做的一些准备划工作。一般包含以下内容&#xff1a;5W1H 目的、测试范围、测试进度安排、测试人员、测试环境、测试方法工具&#xff0c;风险评估 &#xff08;w…

ABB、FANUC机器人点位加速度用法

机器人在点位与点位之间的运动&#xff0c;会存在速度上的变化&#xff0c;加速度指令的添加可以减小机器人在运动中&#xff0c;由高速到低速间惯性的带来的影响&#xff0c;修正机器人的路径误差&#xff0c;让机器人的运动更加顺滑。 一、ABB机器人指令添加 ABB机器人加速…

TCHouse-C

一.概括 1.地域&#xff08;Region&#xff09; 地域&#xff08;Region&#xff09;指腾讯云数据仓库 TCHouse-C 物理服务器所在的地理区域。腾讯云不同地域之间网络完全隔离&#xff0c;购买后不能更换。&#xff08;地域一旦选定&#xff0c;购买后无法更改。&#xff09;…

IP地址的主要功能及其在网络中的重要性

在当今数字化时代&#xff0c;互联网已经成为人们生活和工作中不可或缺的一部分。而IP地址&#xff08;Internet Protocol Address&#xff09;作为互联网中的关键组成部分&#xff0c;发挥着至关重要的作用。本文将探讨IP地址的主要功能以及其在网络中的重要性。 IP地址查询&…

解决在嵌入式系统开发编译时遇到的“no definition for ‘xxx‘在xxx.o文件中”BUG

提示&#xff1a;本文章是自己折腾嵌入式系统开发过程学习记录 解决在嵌入式系统开发编译时遇到的“no definition for xxx在xxx.o文件中”BUG BUG描述一、编译开发环境开发语言和库 二、问题分析知识点说明函数声明&#xff1a;函数定义&#xff1a; 三、解决方案1. 检查函数声…

el-image实现旋转修改保存

2024.4.8今天我学习了用el-image组件如何实现图片的旋转然后保存旋转之后的图片&#xff0c; 代码如下&#xff1a; 一、新增确定按钮。 <template><el-image src/assets/xxx/xxx clickclickImage(/assets/xxx/xxx)/> </template><script> export d…