当前位置: 首页 > news >正文

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

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节点

相关文章:

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

1.二叉搜索树的定义 二叉搜索树要么是空树&#xff0c;要么是满足以下特性的树 &#xff08;1&#xff09;左子树不为空&#xff0c;那么左子树左右节点的值都小于根节点的值 &#xff08;2&#xff09;右子树不为空&#xff0c;那么右子树左右节点的值都大于根节点的值 &#…...

【愚公系列】《Python网络爬虫从入门到精通》036-DataFrame日期数据处理

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…...

C++(蓝桥杯常考点)

前言&#xff1a;这个是针对于蓝桥杯竞赛常考的C内容&#xff0c;容器这些等下棋期再讲 C 在DEVC中注释和取消注释的方法&#xff1a;ctrl/ ASCII值&#xff08;常用的&#xff09;&#xff1a; A-Z:65-90 a-z:97-122 0-9:48-57 换行/n:10科学计数法&#xff1a;eg&#xff1a…...

支付宝 IoT 设备入门宝典(下)设备经营篇

上篇介绍了支付宝 IoT 设备管理&#xff0c;但除了这些基础功能外&#xff0c;商户还可以利用设备进行一些运营动作&#xff0c;让设备更好的帮助自己&#xff0c;本篇就会以设备经营为中心&#xff0c;介绍常见的设备相关能力和问题解决方案。如果对上篇感兴趣&#xff0c;可以…...

蓝桥杯 之 填空题-位运算与循环

文章目录 循环握手问题门牌制作-循环小球反弹幸运数艺术与篮球跑步卡片 位运算3个1美丽的2024 位运算 可以关注这个Lowbit(x) 如何判断最低位是否是1&#xff1f; num&1 1就说明num最低位是1 循环 循环 握手问题 握手问题 思路分析&#xff1a; 可以直接计算出来&…...

iOS逆向工程概述与学习路线图

iOS逆向工程概述与学习路线图 欢迎各位加入我的iOS逆向工程专栏&#xff01;在这个系列的第一篇文章中&#xff0c;我将为大家介绍iOS逆向工程的基本概念、应用场景以及完整的学习路线图&#xff0c;帮助大家建立清晰的学习框架。 什么是iOS逆向工程&#xff1f; 逆向工程&a…...

DeepSeek 助力 Vue3 开发:打造丝滑的时间选择器(Time Picker)

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的时间选择器(Time Picker)📚前言📚页面效果📚指令输入…...

基于 Ingress-Nginx 实现 mTLS 双向认证

目录 背景描述&#xff1a; TLS 和 MTLS 之间的差异 通过自签名证书启用双向 TLS 1. 生成证书 (1) 生成 CA&#xff08;根证书颁发机构&#xff09; (2) 生成 CA&#xff08;根证书颁发机构&#xff09; (3) 生成客户端证书 2. 在 Kubernetes 中配置 mTLS &#x…...

学到什么记什么(25.3.3)

Upload-labs 今日重新做了一下文件上传漏洞&#xff0c;这里第一题之前采用直接抓包改后缀名.jpg为.php&#xff0c;再写入一句话<?php phpinfo();?>然后放行&#xff0c;得到图片地址&#xff08;可复制&#xff09;&#xff0c;本来直接访问图片地址即可得到敏感信息…...

【子网掩码计算器:Python + Tkinter 实现】

子网掩码计算器&#xff1a;Python Tkinter 实现 引言代码功能概述代码实现思路1. 界面设计2. 功能实现3. 事件处理 子网掩码计算器实现步骤1. 导入必要的库2. 定义主窗口类 SubnetCalculatorApp3. 创建菜单栏4. 创建界面组件5. 判断 IP 地址类别6. 计算子网信息7. 其他功能函…...

《解锁HarmonyOS NEXT高阶玩法:艺术图像识别功能开发全攻略》

在当今数字化时代&#xff0c;AI技术不断拓展其应用边界&#xff0c;为各行业带来前所未有的变革。在艺术领域&#xff0c;AI图像识别技术能够帮助艺术从业者、爱好者快速识别艺术品风格、作者&#xff0c;甚至挖掘艺术品背后的历史文化信息。本文将结合HarmonyOS NEXT API 12及…...

Spring Boot的启动流程

Spring Boot 的启动流程是一个复杂且有序的过程&#xff1a; 创建SpringApplication实例 — 调用run方法 — 启动完成(发布应用启动事件&#xff0c;配置环境&#xff0c;创建ApplicationContext&#xff0c;准备ApplicationContext&#xff0c;刷新ApplicationContext[【创建B…...

【通俗讲解电子电路】——从零开始理解生活中的电路(三)

实际应用案例&#xff1a;生活中的电子电路 ——拆解你身边的“隐形工程师” 1. 手电筒电路&#xff1a;最简单的直流系统 电路组成 电源&#xff1a;2节1.5V电池&#xff08;串联3V&#xff09;。 开关&#xff1a;按钮控制回路通断。 LED&#xff1a;发光二极管&#xff…...

TypeScript系列01-类型系统全解析

本文总结了 TypeScript 的类型系统基础&#xff0c;涵盖了&#xff1a; TypeScript 的价值&#xff1a;静态类型检查为 JavaScript 添加了类型安全保障基本类型系统&#xff1a;从原始类型到特殊类型&#xff08;any、unknown、never&#xff09;的完整介绍类型注解与推断&…...

ragflow-mysql 启动失败案例分析

一、问题描述 1.拉取RAGflow镜像失败 dependency failed to start: container ragflow-mysql is unhealthy2. 查询日志 docker logs ragflow-mysql显示 出现[rootlocalhost docker]# docker logs ragflow-mysql Fatal glibc error: CPU does not support x86-64-v2 Fatal …...

SslConnection::SslConnection()详解

一、&#x1f50d; SslConnection::SslConnection() 详解 这个构造函数的主要作用是&#xff1a; 创建 SSL 对象创建 BIO&#xff08;I/O 缓冲区&#xff09;初始化 SSL 服务器模式绑定回调函数&#xff08;onRead() 处理接收数据&#xff09; &#x1f4cc; 1. 初始化 SSL 相…...

unity lua属性绑定刷新

我们现在有一个 角色属性类叫heroModel,内容如下,当heroModel中的等级发生变化的时候&#xff0c;我们需要刷新界面显示等级信息&#xff0c;通常我们是在收到等级升级成功的协议的时候&#xff0c;发送一个事件&#xff0c;UI界面接受到这个事件的时候&#xff0c;刷新一下等级…...

Self-Pro: A Self-Prompt and Tuning Framework for Graph Neural Networks

Self-Pro: A Self-Prompt and Tuning Framework for Graph Neural Networks ​#paper/GFM/GNN-BASED#​ #paper/⭐⭐⭐#​ 注意&#xff1a;这篇文章是每个图一个GCN模型&#xff0c;而不是所有图一个GCN 模型 算是最早的涉及异配图的prompt了 贡献和动机&#xff1a; 非对…...

企业级-数据分类分级详细方案

一、方案背景 在数字化时代,数据成为企业和组织的核心资产。随着数据量的快速增长和数据应用场景的不断拓展,如何有效地管理和保护数据,确保数据的安全性、合规性和可用性,成为了亟待解决的问题。数据分类分级作为数据管理的基础工作,能够帮助企业清晰地了解自身的数据资…...

本地部署Qwen2.5-VL-7B-Instruct模型

本地部署Qwen2.5-VL-7B-Instruct模型 本地部署Permalink **创建环境** conda create -n qwenvl python3.11 -y# 报错&#xff1a; Solving environment: failedPackagesNotFoundError: The following packages are not available from current channels:# 处理&#xff1a; c…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...