算法练习-二叉搜索树中的搜索(思路+流程图+代码)

难度参考

        难度:中等

        分类:二叉树

        难度与分类由我所参与的培训课程提供,但需要注意的是,难度与分类仅供参考。且所在课程未提供测试平台,故实现代码主要为自行测试的那种,以下内容均为个人笔记,旨在督促自己认真学习。

题目

        给定二叉搜索树(BST)的根节点和一个值。你需要在BST中找到节点值等于给定值的节点。返回以该节点为根的子树。如果节点不存在,则返回NULL.
        示例1:
        输入:root=[4,2,7,1,3],val=2
        输出:[2,1,3]

        示例2:
        输入:root=[4,2,7,1,3],val=5
        输出:[]
        提示:
        树中节点数在[1,5000]范围内
        1<=Node.Va1<=10(7)
        root是二叉搜索树
        1<=val<=10(7)
        额外:
        希望你可以尝试使用迭代法,尤其要考虑二叉搜索树的特性,来优化迭代。

思路

        这个问题要求在一个二叉搜索树中查找一个特定值的节点,并且返回以这个节点为根的子树。如果找不到这个值,则返回NULL。由于这是一个二叉搜索树,我们可以利用其特性来指导搜索过程,使之比一般的二叉树更高效。在二叉搜索树中,对于任何节点,其左子树中的所有节点都小于这个节点,而右子树中的所有节点都大于这个节点。

        基于这个性质,我们可以使用如下思路来进行查找:

  1. 从树的根节点开始搜索。
  2. 比较当前节点的值与目标值:
    • 如果当前节点的值等于目标值,那么我们找到了目标节点,返回这个节点即可。
    • 如果目标值小于当前节点的值,那么我们应该在左子树中继续搜索。
    • 如果目标值大于当前节点的值,那么我们应该在右子树中继续搜索。
  3. 如果当前节点是NULL,表示我们已经到达了叶子节点但未找到目标值,此时应该返回NULL。
  4. 重复以上步骤直到找到目标值或遍历到了叶子节点。

示例

        假设我们有如下的二叉搜索树结构:

        4/ \2   7/ \1   3

        现在让我们分两个示例来查找值为2的节点。

        示例一:查找值为2的节点

  1. 我们从根节点开始,也就是值为4的节点。
  2. 因为2小于4,我们向左子树移动。
  3. 现在我们在值为2的节点。我们比较当前节点的值(2)与目标值(2),发现它们相等。
  4. 我们找到了目标节点,并返回这个节点。

        函数返回包含值为2的子树的根,也就是:

    2/ \1   3

        示例二:查找值为5的节点

  1. 我们从根节点开始,也就是值为4的节点。
  2. 因为5大于4,我们向右子树移动。
  3. 现在我们在值为7的节点。因为5小于7,我们向左子树移动。
  4. 在值为7的节点处,并没有左子节点,所以我们到达了NULL。
  5. 我们没有找到目标节点,返回NULL。

梳理

        这样的实现能够工作,因为它依赖于二叉搜索树(Binary Search Tree, BST)的基本性质。在二叉搜索树中,每个节点都满足以下条件:

  1. 节点的左子树中的每个节点的值都小于当前节点的值。
  2. 节点的右子树中的每个节点的值都大于当前节点的值。
  3. 左子树和右子树也分别是二叉搜索树。

        这个性质允许我们使用二分查找的方法快速地在树中定位一个值是否存在。具体到 searchBST 函数中的实现:

  • 开始查找:我们从根节点开始查找。
  • 比较值:我们将目标值与当前节点的值进行比较。
    • 如果目标值与当前节点的值相等,我们就找到了需要的节点,返回它;
    • 如果目标值小于当前节点的值,根据二叉搜索树的性质,我们知道目标值(如果存在于树中)必定在当前节点的左子树中。因此,我们更新当前节点为其左子节点,继续查找;
    • 如果目标值大于当前节点的值,那么目标值(同样如果存在)一定在当前节点的右子树中。因此,我们更新当前节点为其右子节点,继续查找。
  • 终止条件:这个过程会一直进行,直到当前节点为空(这意味着目标值不存在于树中,返回 nullptr)或者找到了一个节点的值等于目标值(返回该节点)。

代码

#include <iostream> // 包含标准输入输出流的库using namespace std; // 使用命名空间std,省去std::前缀struct TreeNode { // 定义二叉树节点结构int val; // 节点存储的值TreeNode *left; // 指向左子树的指针TreeNode *right; // 指向右子树的指针TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} // 初始化构造函数,nullptr表示空指针
};TreeNode* searchBST(TreeNode* root, int val) { // 定义搜索二叉搜索树的函数while (root != nullptr && root->val != val) { // 当树不为空且当前节点值不等于目标值时root = val < root->val ? root->left : root->right; // 判断目标值是在左子树还是右子树}return root; // 返回找到的节点指针,如果没找到则是nullptr
}int main() { // 主函数TreeNode* root = new TreeNode(4); // 创建根节点,赋值为4root->left = new TreeNode(2); // 创建根的左子节点,赋值为2root->right = new TreeNode(7); // 创建根的右子节点,赋值为7root->left->left = new TreeNode(1); // 创建左子节点的左子节点,赋值为1root->left->right = new TreeNode(3); // 创建左子节点的右子节点,赋值为3int search_val = 2; // 设置要查找的值为2TreeNode* result = searchBST(root, search_val); // 调用搜索函数if (result != nullptr) { // 如果搜索结果不为空cout << "搜索到节点值为 " << search_val << " 的节点是:" << result->val << endl;if (result->left != nullptr) // 如果搜索到的节点的左子树不为空cout << "左子节点:" << result->left->val << endl; // 打印左子节点的值if (result->right != nullptr) // 如果搜索到的节点的右子树不为空cout << "右子节点:" << result->right->val << endl; // 打印右子节点的值} else { // 如果搜索结果为空cout << "未找到节点值为 " << search_val << " 的节点" << endl; // 表明没找到节点}search_val = 5; // 设置要查找的值为5result = searchBST(root, search_val); // 再次调用搜索函数if (result != nullptr) { // 如果搜索结果不为空cout << "搜索到节点值为 " << search_val << " 的节点是:" << result->val << endl;if (result->left != nullptr) // 如果搜索到的节点的左子树不为空cout << "左子节点:" << result->left->val << endl;if (result->right != nullptr) // 如果搜索到的节点的右子树不为空cout << "右子节点:" << result->right->val << endl;} else { // 如果搜索结果为空cout << "未找到节点值为 " << search_val << " 的节点" << endl; // 表明没找到节点}// 释放动态分配的内存(没写,懒)return 0; // 主函数结束,返回0
}  

        时间复杂度:O(n)

        空间复杂度:O(n)

打卡

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

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

相关文章

活字格V9 嵌入的html与活字格页面数据交互

不想看分析请直接跳到解决方案 项目场景&#xff1a; 活字格V9 嵌入的html与活字格页面的数据交互&#xff08;传值&#xff09;&#xff0c;嵌入的html用了WebSocket来控制硬件&#xff0c;获取的数据无法回传到活字格页面上&#xff0c;且嵌入的html无法使用活字格内置的js及…

第三百一十回

我们在上一章回中介绍了"再谈ListView中的分隔线"&#xff0c;本章回中将介绍showMenu的用法.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在第一百六十三回中介绍了showMenu相关的内容&#xff0c;它主要用来显示移动PopupMenu在页面中的位置…

Git、github与gitee码云

1.git核心是两个仓库&#xff1a;本地仓库和远程仓库 主要用于团队合作和代码版本控制&#xff08;个人现有版本代码出错可回溯上个提交版本的代码&#xff09; 远程仓库国际主流githut&#xff0c;但外网速度问题&#xff0c;国内可使用码云gitee github&#xff1a;https:…

【开源】JAVA+Vue.js实现在线课程教学系统

目录 一、摘要1.1 系统介绍1.2 项目录屏 二、研究内容2.1 课程类型管理模块2.2 课程管理模块2.3 课时管理模块2.4 课程交互模块2.5 系统基础模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示4.1 管理后台4.2 用户网页 五、样例代码5.1 新增课程类型5.2 网站登录5.3 课…

vue3+vite+ts 配置commit强制码提交规范配置 commitlint

配置 git 提交时的 commit 信息&#xff0c;统一提交 git 提交规范 安装命令: npm install -g commitizen npm i cz-customizable npm i commitlint/config-conventional commitlint/cli -D 文件配置 根路径创建文件 commitlint.config.js module.exports {// 继承的规…

Backtrader 文档学习- Plotting -Plotting on the same axis

Backtrader 文档学习- Plotting -Plotting on the same axis 1.概述 在同一轴上绘图&#xff0c;绘图是在同一空间上绘制原始数据和稍微(随机)修改的数据&#xff0c;但不是在同一轴上。 核心代码&#xff0c;data数据正负50点。 # The filter which changes the close pri…

java面试题:MySQL中的各种JOIN的区别

表关联是频率非常高的一种数据库操作&#xff0c;在MySQL中&#xff0c;这种JOIN操作有很多类型&#xff0c;包括内联接、左外连接、右外连接等等&#xff0c;而每种连接的含义都不一样&#xff0c;如果死记硬背&#xff0c;不仅很难记住&#xff0c;而且也容易搞混淆&#xff…

JAVA Web 学习(三)Web服务架构

五、软件架构模式——MVC MVC是一种 分层开发的模式 &#xff0c;其中&#xff1a;M-Model&#xff0c;业务模型&#xff0c;处理业务&#xff1b;V&#xff1a;View&#xff0c;视图&#xff0c;界面展示&#xff1b;C&#xff1a;Controller&#xff0c;控制器&#xff0c;处…

基于华为云欧拉操作系统(HCE OS)容器化部署传统应用(Redis+Postgresql+Git+SpringBoot+Nginx)

写在前面 博文内容为 华为云欧拉操作系统入门级开发者认证(HCCDA – Huawei Cloud EulerOS)实验笔记整理认证地址&#xff1a;https://edu.huaweicloud.com/certificationindex/developer/9bf91efb086a448ab4331a2f53a4d3a1博文内容涉及一个传统 Springboot 应用HCE部署&#x…

JavaScript 入门 完整版

目录 第一个知识点&#xff1a;引入js文件 内部引用: 外部引用: 第二个知识点&#xff1a;javascript的基本语法 定义变量&#xff1a; 条件控制(if - else if - else) 第三个知识点&#xff1a;javascript里的数据类型、运算符&#xff1a; 数字类型 字符串类型 布尔…

新型Black Matter勒索病毒,勒索300万美金

前言 BlackMatter勒索病毒是一款基于RAAS模式的新型勒索病毒&#xff0c;该勒索病毒组织成立于2021年7月&#xff0c;该勒索病毒黑客组织对外宣称&#xff0c;已经整合了DarkSide、REvil和LockBit等勒索病毒的最佳功能特点。 勒索病毒黑客组织曾表示不会对医疗保健、关键基础设…

ncc匹配(五,匹配提速的思考)

感觉ncc&#xff08;相关系数匹配&#xff09;与bpnet&#xff08;bp神经网络&#xff09;相似&#xff0c;但ncc简洁方便快速&#xff0c;计算量小&#xff0c;问题点也少。 都有归一化的动作&#xff0c;都是相关性的学习&#xff0c;不过bpnet可以学习多种类型&#xff0c;…

RedissonClient妙用-分布式布隆过滤器

目录 布隆过滤器介绍 布隆过滤器的落地应用场景 高并发处理 多个过滤器平滑切换 分析总结 布隆过滤器介绍 布隆过滤器&#xff08;Bloom Filter&#xff09;是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是…

云服务器总结

1.服务器重装系后远程连接报错 Host key for xxx.xxx.xxx.xxx has changed and you have requested strict checking. 问题原因 ssh会把你每个你访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts。当下次访问相同计算机时&#xff0c;OpenSSH会核对公钥。如果公钥不…

js手写Promise(下)

目录 resolve与reject的调用时机封装优化 回调返回PromiseisPromise手动调用then 微队列catchresolverejectall传入的序列为空传入的值非Promise race完整的Promise代码 如果没有看过上半部分的铁铁可以看看这篇文章 js手写Promise&#xff08;上&#xff09; resolve与reject…

kmeans聚类选择最优K值python实现

Kmeans算法中K值的确定是很重要的。 下面利用python中sklearn模块进行数据聚类的K值选择 数据集自制数据集&#xff0c;格式如下&#xff1a; 维度为3。 ①手肘法 手肘法的核心指标是SSE(sum of the squared errors&#xff0c;误差平方和)&#xff0c; 其中&#xff0c;Ci是第…

最近vscode链接Autodl出现的问题

最近vscode链接Autodl出现的问题 一、问题的概述 在使用vscode连接autodl远程服务器的时候&#xff0c;在vscode的右下角出现了&#xff0c;以下的问题提示&#xff1a; 远程主机可能不符合glibc和libstdc VS Code服务器的先决条件 二、问题的原因 vscode版本过高的问题&…

搭建yum仓库服务器

安装 1.安装linux 1.1安装依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 1.2下载 cd /opt/nginx wget http://nginx.org/download/nginx-1.25.3.tar.gz 1.3解压 tar -xvf nginx-1.25.3.tar.gz 1.4配置 cd nginx-1.25.3 ./configure --pre…

职业性格测试在求职应聘跳槽中的应用

人的性格总是千奇百怪&#xff0c;有的人总是想迎接挑战&#xff0c;超越自己&#xff0c;不停的奔着高处走&#xff0c;然而有的人总是喜欢随遇而安&#xff0c;踏踏实实一辈子&#xff0c;有份安稳的工作&#xff0c;有吃有喝就好。那么对于哪些喜欢迎接挑战&#xff0c;但又…

Linux下的crontab定时执行任务命令详解

在LINUX中&#xff0c;周期执行的任务一般由cron这个守护进程来处理[ps -ef|grep cron]。cron读取一个或多个配置文件&#xff0c;这些配置文件中包含了命令行及其调用时间。 cron的配置文件称为“crontab”&#xff0c;是“cron table”的简写。 一、cron服务   cron是一个…