数据结构:二叉搜索树(排序树)

1.二叉搜索树的定义

二叉搜索树要么是空树,要么是满足以下特性的树

(1)左子树不为空,那么左子树左右节点的值都小于根节点的值

(2)右子树不为空,那么右子树左右节点的值都大于根节点的值

(3)其所有子树也满足二叉搜索树性质

(4)二叉搜索树有两种形态,一种是支持插入冗余值,一种是不支持的(一般默认不支持冗余)

简单来说就是左边节点值 < 根节点值 < 右边节点值

二叉搜索树又叫二叉排序树,这是因为如果对他进行中序遍历,将会得到一组升序排序的数据

2.二叉搜索树的性能

二叉搜索树的搜索次数是等于树的高度的

最优情况:对于类似完全二叉树的树结构,时间复杂度可以达到O(logn)

最差情况:对于几乎所有数据都单侧分布的情况,时间复杂度会到O(n)

为了使他保持最优的性能,我们后续会引入平衡的概念,使他保持左右子树高度差小于等于1

3.部分实现非冗余二叉搜索树

节点基本结构搭建:

对于bstree的搭建:只需要加一个private的根节点指针即可

3.1插入

(1)若树为空,则直接新建节点,然后把新节点的地址给bs树的根节点,返回true,表示插入成功

(2)若树不为空,则判断key和当前节点的值的大小

若key小于当前节点的值:往左边搜索

若大于当前节点的值:往右边搜索

若等于当前节点值:直接返回false

如果我只用一个cur指针,是不能完成节点的链接的,因为链接节点的是cur的直接根节点,也就是prvcur节点,所以这里我们才创建一个prvnode指针,就是用于把新节点和bs树进行连接的。

(3)找到之后判断key于待链接节点的值的大小决定插入在左侧还是右侧


接下来进入测试阶段,不过在测试之前我们需要写一个中序遍历的方法,以便更直观的检查逻辑是否正确

我们利用递归的方式实现,结束条件是节点为空。

由于二叉搜索树左子树 < 根节点 < 右子树的性质,我们使用中序遍历可以实现升序输出

不过这里有个问题,我们需要传递bstree的private变量,可以使用友元,实现get函数等方法去获取m_root,现在我们介绍一个新的方式

                                                         封装进类中

我们在_inorder中实现具体功能,然后封装到inorder中,inorder主要用于调用m_root给_inorder传递参数

3.2查找

由于我们在插入部分已经进行过查找数据,所以我们只需要对insert的代码稍微改一下即可

下面我们进行调试

对1的查找成功,对11的查找失败,符合预期

3.3删除

对于删除,总共有四种情况

情况1:delete节点为叶子节点

解决方法:找到该节点后让他的父节点指向nullptr,并释放该节点空间

情况2:delete节点只有左节点

解决方法:让他的父节点指向他的那一侧指向delete的左节点

情况3:delete节点只有右节点

解决方法:让他的父节点指向他的那一侧指向delete的右节点

情况4:delete节点左右节点均有

解决方法:寻找delete左子树的最大节点,或者delete右子树的最小节点,然后交换delete位置的值与replace节点的值,让replace的父节点空余的一侧指向replace节点的左侧(从左子树找时),或者右侧(从右子树找时)。最后释放replace位置的空间

疑问一:为什么是寻找delete左子树的最大节点,或者delete右子树的最小节点?

答:

因为我们需要保持二叉搜索树的排序结构,只能从左树找一个最大数据(保证替换后根大于左树,且由于是从左树找的数据,必然也是小于右树的数据的),或者从右数找一个最小数据(和左树同理)

疑问二:寻找到的replace节点为什么可以直接让其父节点接入另一侧?

答:

因为replace已经是最左或者最右节点,所以不可能两侧都有节点,最多只有另一侧有节点。

特殊情况分析:

(1)对于delete节点有左右节点,且replace的节点就是左子树根节点,或右子树根节点

我们需要把replace的父节点设置为cur,而不是空,否则会有空指针访问。

并且replace父节点的指向侧也不是确定的,这种情况下和会更新replace父节点的情况,父节点的指向侧是相反的

(2)对于delete节点只有右节点或左节点,且delete节点为搜索树的根节点

由于这种基于情况1,2,3的情况下,我们需要释放delete节点的空间,所以根节点需要删除就涉及根节点的指针指向变更。

我们对cur==m_root的情况用if语句单独处理,让m_root指向cur->left或cur->right


代码实现:

(1)大框架搭建:我们使用insert的代码作为查找大框架

我们的代码写在找到delete节点cur的位置

(2)对情况1-3进行处理,并把特殊情况1纳入考虑

由于右侧为空/左侧为空的情况可以兼容两侧为空的情况,所以我们不用单独处理两侧为空的情况

(1)cur左为空

对于cur左为空且cur为根节点:更改m_root,指向cur有节点的一侧,也就是右侧

对于cur非根节点的情况:让父节点指向cur的那一侧指向cur有节点的一侧

(2)cur右为空

(3)cur左右非空

我们实现的是从左子树中查找最大节点,也可以换成从右子树查找最小节点

第一步:

查找replace节点:循环更改replace与replaceprv指针,直到replace指向的节点右侧为空

第二步:

交换delete与replace节点的值

第三步:让replace父节点指向replace节点的左侧

注意:

若replace父节点就是cur,说明节点就在cur的左侧,用父节点左侧指向replace节点左侧。

若replace父节点不为cur,说明进入了循环,而replace父节点就是上一次的replace,replace一直在往右走,所以其父节点一定是右侧指向replace节点

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

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

相关文章

Observability:使用 Elastic Agent 跟踪你的 Steam Deck 游戏

作者&#xff1a;来自 Elastic AndersonQ 让我们以不同的方式看待可观察性&#xff0c;并使用我们最喜欢的工具来监控我们的游戏性能。今天&#xff0c;我们将探讨如何使用 Elastic Agent 来监控 Steam Deck&#xff0c;以便我们可以看到我们玩得最多的游戏、它们消耗了多少资源…

20250227解决飞凌OK3588-C的linux R4通过adb拷贝文件速度过慢的问题

20250227解决飞凌OK3588-C的linux R4通过adb拷贝文件速度过慢的问题 2025/2/27 16:51 缘起&#xff1a;最近测试OK3588-C的最新的R1版本的SDK&#xff0c;adb pull的速度为28.8 MB/s Z:\version\OK3588-C_Linux5.10.209Qt5.15.10_用户资料_R1 我司使用4线的USB2.0&#xff0c;…

cesium+vue3自定义HTML实体弹窗、加高德路网、防实体漂浮、让用户画圆、鹰眼

一、基础使用&#xff1a;Cesium.js基础使用&#xff08;vue&#xff09;-CSDN博客 1、基础路径 为 Cesium 库设置一个全局变量 CESIUM_BASE_URL&#xff0c;用于指定 Cesium 的资源文件&#xff08;如 WebGL shaders、纹理、字体等&#xff09;的 示例场景&#xff1a;假设你…

C# Unity 唐老狮 No.4 模拟面试题

本文章不作任何商业用途 仅作学习与交流 安利唐老狮与其他老师合作的网站,内有大量免费资源和优质付费资源,我入门就是看唐老师的课程 打好坚实的基础非常非常重要: 全部 - 游习堂 - 唐老狮创立的游戏开发在线学习平台 - Powered By EduSoho 如果你发现了文章内特殊的字体格式,…

Docker 学习(二)——基于Registry、Harbor搭建私有仓库

Docker仓库是集中存储和管理Docker镜像的平台&#xff0c;支持镜像的上传、下载、版本管理等功能。 一、Docker仓库分类 1.公有仓库 Docker Hub&#xff1a;官方默认公共仓库&#xff0c;提供超过10万镜像&#xff0c;支持用户上传和管理镜像。 第三方平台&#xff1a;如阿里…

Oracle 数据库基础入门(四):分组与联表查询的深度探索(上)

在 Oracle 数据库的学习进程中&#xff0c;分组查询与联表查询是进阶阶段的重要知识点&#xff0c;它们如同数据库操作的魔法棒&#xff0c;能够从复杂的数据中挖掘出有价值的信息。对于 Java 全栈开发者而言&#xff0c;掌握这些技能不仅有助于高效地处理数据库数据&#xff0…

Lua | 每日一练 (4)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Lua | 每日一练 (4)题目参考答案线程和协程调度方式上…

我代表中国受邀在亚马逊云科技全球云计算大会re:Invent中技术演讲

大家好我是小李哥&#xff0c;本名叫李少奕&#xff0c;目前在一家金融行业公司担任首席云计算工程师。去年5月很荣幸在全球千万名开发者中被选为了全球亚马逊云科技认证技术专家&#xff08;AWS Hero&#xff09;&#xff0c;是近10年来大陆地区仅有的第9名大陆专家。同时作为…

C++蓝桥杯基础篇(七)

片头 嗨~小伙伴们&#xff0c;大家好&#xff01;今天我们来一起学习蓝桥杯基础篇&#xff08;七&#xff09;&#xff0c;学习相关字符串的知识&#xff0c;准备好了吗&#xff1f;咱们开始咯&#xff01; 一、字符与整数的联系——ASCII码 每个常用字符都对应一个-128~127的…

显式 GC 的使用:留与去,如何选择?

目录 一、什么是显式 GC&#xff1f; &#xff08;一&#xff09; 垃圾回收的基本原理 &#xff08;二&#xff09;显式 GC 方法和行为 1. System.gc() 方法 2. 显式 GC 的行为 &#xff08;三&#xff09;显式 GC 的使用场景与风险 1. JVM 如何处理显式 GC 2. 显式 GC…

2025.03.03(第一天)

1、常见的高危端口号有哪些&#xff0c;并涉及到哪些攻击方式 端口号服务常见攻击方式21FTP匿名登录、文件上传漏洞22SSH暴力破解、密钥泄露、中间人攻击53DNSDNS劫持、DNS缓存投毒、DDoS放大攻击80/443HTTP/HTTPSSQL注入1433MSSQL暴力破解、SQL注入、远程代码执行3306MySQLSQ…

MySQL数据库基本概念

目录 什么是数据库 从软件角度出发 从网络角度出发 MySQL数据库的client端和sever端进程 mysql的client端进程连接sever端进程 mysql配置文件 MySql存储引擎 MySQL的sql语句的分类 数据库 库的操作 创建数据库 不同校验规则对查询的数据的影响 不区分大小写 区…

确保移动设备上机器学习的安全性:挑战与最佳实践

随着企业不断推出更智能、个性化且响应迅速的体验&#xff0c;AI处理能力在移动设备中的普及&#xff0c;促使了机器学习&#xff08;ML&#xff09;本地集成的应用和SDK的快速发展。2024年谷歌I/O大会报告中强调了这一趋势&#xff0c;谷歌鼓励开发者在移动应用中使用本地机器…

【Mac】2025-MacOS系统下常用的开发环境配置

早期版本的一个环境搭建参考 1、brew Mac自带终端运行&#xff1a; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" Installation successful!成功后运行三行命令后更新环境&#xff08;xxx是mac的username&a…

计算机毕业设计SpringBoot+Vue.js美食推荐系统商城(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

【Linux网络#14】:数据链路层(以太网 局域网通信 ARP协议 ARP 欺骗 DDos 攻击)

&#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;Linux—登神长阶 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f49e; &#x1f49e; &#x1f49e; 生活总是不会一帆风顺&#x…

001-码云操作

码云操作 一、配置公钥1.官网地址1.进入 git bash2.查看生成的公钥3.设置到 Gitee4.测试 二、初始化一个项目1.新建仓库 一、配置公钥 方便后续提交代码不用填写密码 1.官网地址 官网地址&#xff1a;https://gitee.com/Git码云教程&#xff1a;https://gitee.com/help/arti…

Android 获取jks的SHA1值:java.io.IOException: Invalid keystore format

命令生成 keytool -list -v -keystore 全路径.jks -alias 别名 -storepass 密码 -keypass 密码 1、遇到 的问题&#xff1a; 通过快捷键 ‘win r’ 启动的小黑框运行上面的命令会出现下面这个错误keytool 错误: java.io.IOException: Invalid keystore format 2、解决问题 …

项目准备(flask+pyhon+MachineLearning)- 1

目录 这是一篇学习笔记 1. 搭建项目 2.前期准备工作 3.创建用户(user)模板 这是一篇学习笔记 目的&#xff1a;用flask快速实现发布有关机器学习的项目&#xff0c;掌握flask框架&#xff0c;机器学习模型的存储和调用。 1. 搭建项目 使用pycharm创建项目&#xff0c;fl…

DeepSeek开源周Day5: 3FS存储系统与AI数据处理新标杆

项目地址&#xff1a; GitHub - deepseek-ai/3FS: A high-performance distributed file system designed to address the challenges of AI training and inference workloads.GitHub - deepseek-ai/smallpond: A lightweight data processing framework built on DuckDB and…