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

红黑树的原理+实现

文章目录

  • 红黑树
    • 定义
    • 性质
    • 红黑树的插入
    • 动态效果演示
  • 代码
  • 测试红黑树

红黑树

定义

在这里插入图片描述

红黑树是一个近似平衡的搜索树,关于近似平衡主要体现在最长路径小于最短路径的两倍(我认为这是红黑树核心原则),为了达到这个原则,红黑树所有节点都增加了一个存储位表示节点的颜色(红或黑),并规定了一些性质来达到“近似平衡”

性质

  1. 每个节点不是红色就是黑色
  2. 根节点时黑色
  3. 如果一个节点是红色,则它的两个孩子节点是黑色
  4. 对于每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点
  5. 每个叶子节点都是黑色的(空节点也算为叶子节点)

对于这些性质有一些推论:

  • 红色节点的父节点一定是黑色节点
  • 何时红黑树的路径最短?——该树所有节点都是黑色
  • 何时红黑树的路径最长?——该树红色节点和黑色节点交替

红黑树的插入

插入之前我们首先要搞明白一个问题,插入的节点默认应该应该是什么颜色(然后根据插入后调整)?


插入的节点如果都设置为黑色,一定会违反性质4,。如果插入的是红色节点,分为两种情况:如果插入节点的父节点为黑色,则不需要调整,如果插入节点的父节点为红色,则需要进一步调整。
从上可知,如果默认插入的是黑色100%需要调整,而默认插入的是红色,则有50%需要调整,所以我们这里选择默认插入红色节点

红黑树的插入需要记住三种需要调整的特殊情况:下面所有情况中 cur 为当前插入后违反红黑树规则的节点,


  • 情况一: curparent为红,grandparent为黑,uncle存在且为红
    在这里插入图片描述
    这种情况不需要旋转只需要调整节点的颜色即可,将parentuncle变成黑色,grandparent变成红色(这里有特殊情况,如果grandparent为根节点时)
    在这里插入图片描述
    ok到这里我们观察一下,grandparent为红色,如果grandparent的父节点为红色(因为grandparent原本为黑色,所以其父节点有可能为红色)则又会出现两个连续的红色,所以情况一结束后还要继续向上检查,这时我们将cur=grandparent继续向上遍历,继续分析下一层的情况
    在这里插入图片描述

  • 情况二:curparent为红,grandparent为黑,uncle为黑/不存在
    在这里插入图片描述
    这里有两种小情况我们先逐一分析,但是这两种小情况最后的操作都是一样的
    • uncle不存在:cur一定为新插入的节点而不是整个向上调整循环中的一次,因为如果cur不是新插入的节点,则curparent一定有一个是黑色,分别是从上一层的情况一和情况三变过来的,但是这就不满足红黑树的定义了。所以cur一定是新插入的节点
    • uncle存在且为黑:那么cur一定是黑色的,现在是红色是因为上一层结束后改成了红色,继续向上遍历的结果
      如何处理情况二?——右单旋+调整颜色
      在这里插入图片描述
      ok到这里情况二调整完毕了。是否需要继续向上调整了?答案是不用!因为整个局部的子树调整完的根节点变成黑色了,并不会和其父节点的颜色发生冲突,所以在 整个三个情况中只要调整完之后的根节点变成了黑色,就不用向上遍历了

  • 情况三:curparent为红,grandparent为黑,uncle为黑/不存在,但是curparent的右节点
    在这里插入图片描述
    如何处理情况三?——局部旋转!+ 转换情况二
    在这里插入图片描述
    这时旋转完之后的树是不是很眼熟?就是情况二,只需要交换一下curparent指针的执行进入下一次的循环即可。
    这里还有另外一个思路就是:局部旋转之后直接执行情况二的右单旋,最后直接break跳出循环。两者思路其实是一模一样的

动态效果演示

以升序插入
请添加图片描述
以降序插入
请添加图片描述
随机插入
请添加图片描述

代码

代码仓库

测试红黑树

为了测试我们写出来的红黑树是否符合要求,我们可以写一个isbalance函数,主要判断:

  1. 不能出现连续的红色节点
  2. 每条路径的黑色节点是否相同

两个条件分别使用不同的函数判断

具体代码实现如下:

 bool parent_isRed(Node *root) // 判断红色节点的父节点是不是黑色节点{if (root == nullptr){return true;}if (root->_col == RED && root->_parent->_col == RED){return false;}return parent_isRed(root->_left) && parent_isRed(root->_right);}void black_num_is_same(Node *root, std::vector<int> &num, int k = 0) // num存储了每条路径黑色节点的数量{if (root == nullptr){num.push_back(k);return;}if (root->_col == BLACK){k++;}black_num_is_same(root->_left, num, k);black_num_is_same(root->_right, num, k);}
void IsBalnace() // 检查红黑树是否平衡{bool is = parent_isRed(_root);std::vector<int> num;black_num_is_same(_root, num);bool it = true;int first = num[0];for (const auto &e : num){if (e != first){it = false;break;}}if (it && is){std::cout << "it is a redblackTree" << std::endl;}else{std::cout << "it is not a redblackTree" << std::endl;}}

检测函数写完我们取1000个随机数向红黑树插入,并用isblance 检查是否平衡:
测试代码
输出结果:
在这里插入图片描述

相关文章:

红黑树的原理+实现

文章目录红黑树定义性质红黑树的插入动态效果演示代码测试红黑树红黑树 定义 红黑树是一个近似平衡的搜索树&#xff0c;关于近似平衡主要体现在最长路径小于最短路径的两倍&#xff08;我认为这是红黑树核心原则&#xff09;&#xff0c;为了达到这个原则&#xff0c;红黑树所…...

用于非线性时间序列预测的稀疏局部线性和邻域嵌入(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

使用 Vue3 重构 Vue2 项目

目录前言&#xff1a;一、项目整体效果展示二、项目下载使用方法三、为什么要重构项目四、重构的流程五、步骤中的 bug 以及解决方式六、未解决的问题总结&#xff1a;前言&#xff1a; 2020年9月18日&#xff0c;vue3正式版发布了&#xff0c;前几天学习完成后&#xff0c;我决…...

Hive学习——单机版Hive的安装

目录 一、基本概念 (一)什么是Hive (二)优势和特点 (三)Hive元数据管理 二、Hive环境搭建 1.自动安装脚本 2./opt/soft/hive312/conf目录下创建hive配置文件hive-site.xml 3.拷贝一个jar包到hive下面的lib目录下 4.删除hive的guava&#xff0c;拷贝hadoop下的guava 5…...

uprobe 实战

观测数据源 目前按照我的理解&#xff0c;和trace相关的常用数据源–探针 大致分为四类。 内核 Trace point kprobe 用户程序 USDT uprobe 在用户程序中&#xff0c;USDT是所谓的静态Tracepoint。和内核代码中的Trace point类似。实现方式是在代码开发时&#xff0c;使用USDT…...

华为OD机试 - 求最大数字(Python)| 真题+思路+考点+代码+岗位

求最大数字 题目 给定一个由纯数字组成以字符串表示的数值,现要求字符串中的每个数字最多只能出现2次,超过的需要进行删除;删除某个重复的数字后,其它数字相对位置保持不变。 如34533,数字3重复超过2次,需要删除其中一个3,删除第一个3后获得最大数值4533 请返回经过删…...

雨水情测报与大坝安全监测系统

压电式雨量传感器产品概述传感器由上盖、外壳和下盖组成&#xff0c;壳体内部有压电片和电路板&#xff0c;可以固定在外径50mm立柱上和气象站横杆上。传感器采用冲击测量原理对单个雨滴重量进行测算&#xff0c;进而计算降雨量。雨滴在降落过程中受到雨滴重量和空气阻力的作用…...

抖音广告投放形式有哪些?新品牌进入抖音怎么建立口碑

坐拥5亿用户的抖音平台&#xff0c;已经成为各大品牌的兵家必争之地。想要在这块宣传的“高地”&#xff0c;做出声量&#xff0c;就必须了解抖音广告投放形式有哪些。这里整理的这份抖音广告投放指南&#xff0c;你一定不能错过。一、抖音为何如此牛想要弄清楚抖音广告的投放形…...

Beefxss使用教程图文教程(超详细)

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 Beefxss一、首次使用二、修改账号密码三、自带练习页面四、简单使用五、工具界面介绍六、功能演示1、网页重定向2、社工弹窗3、功能颜色标识…...

【Python学习笔记】35.Python3 CGI编程(2)

前言 本章继续介绍Python的CGI编程。 通过CGI程序传递checkbox数据 checkbox用于提交一个或者多个选项数据&#xff0c;HTML代码如下&#xff1a; 实例 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>csdn教程(csd…...

博客等级说明

CSDN 博客等级是按照用户的博客积分数量进行的设定&#xff0c;为 Lv1 至 Lv10 共 10 个等级&#xff0c;不同的等级创作者可以享受到不同的权益待遇。例如&#xff0c;皮肤奖励、自定义域名、客服优先处理、自定义文章标签等特权。您需要提高博客积分进一步提升等级&#xff0…...

STL——容器适配器、deque

一、容器适配器 1.适配器 适配器是一种设计模式&#xff08;设计模式是一套被反复使用的、多数人所知晓的、经过分类编目的、代码设计经验的总结&#xff09;&#xff0c;该种模式是将一个类的接口转换成客户希望的另外一个接口。 2.STL标准库中stack和queue的底层结构 stack…...

VBA数组和Excel工作表数据传递

本文介绍如何利用 VBA 的数组&#xff08;Array) 来提高 Excel 单元格和外部数据传输的性能。如果数量比较大&#xff0c;通过 Array 来传输数据比直接操作单元格要快若干倍。 将 Range 的数据写入 VBA Array 将 Range 数据写入 VBA 的数组非常简单。下面的例子演示了用法&am…...

PyQt5保姆级入门教程——从安装到使用

目录 Part1&#xff1a;安装PyQt5 Part 2&#xff1a;PyCharm配置PyQt5 Part 3&#xff1a;PyQt5设计界面介绍 Part 4&#xff1a;PyQt5设计UI 今天看了多个大佬的教程&#xff0c;总算是把PyQt5开发弄好了&#xff0c;每个部分都要看几个人的十分不方便&#xff0c;我十分…...

1.6 epoll实战使用

文章目录1、连接池2、epoll两种工作模式2.1、LT模式2.2、ET模式3、后端开发面试题4、epoll验证1、连接池 将每一个套接字和一块内存进行绑定&#xff0c;连接池就是一个结构体数组&#xff0c;通过链表来维护一个空闲连接。 1、ngx_get_connection(int fd)从空闲链表取一个空闲…...

JDK定时、Spring定时、时间轮定时小结

Timer使用一个线程&#xff0c;一个小根堆。线程执行根上的任务&#xff0c;小根堆会根据执行时间戳重新调整&#xff0c;根上的任务是下一个执行的任务。 DelayedQueue维护一个优先级队列&#xff0c;本质也是一个数组方式的堆。任务生成时也有时间戳&#xff0c;只提供存储。…...

关于cFosSpeed如何配置

cFosSpeed配置一、检查Calibration Done情况二、优化Ping时间和线路校准三、测网速四、cFosSpeed控制台五、配置参数一、检查Calibration Done情况 安装完毕&#xff0c;激活成功后。 右键------>选项------>设置&#xff0c; 打开适配器信息&#xff0c;查看Calibra…...

YOLOV5输出的txt里面有什么猫腻(用于图像分类竞赛中提升图像信息密度)

背景概括&#xff1a; kaggle最近举办了一场医学乳腺癌检测的比赛&#xff08;图像分类&#xff09; 比赛官网地址 给的数据是dcm的专业的医学格式&#xff0c;自己通过DICOM库转为png后&#xff0c;发现该图像胸部不同的患者乳腺大小不一&#xff0c;简言之乳腺的CT有效图在…...

vue+axios常用操作

vueaxios常用操作vue2axios请求拦截依赖项http.jsvue2axios设置请求头依赖项http.js获取并设置请求头api.jsa.vuevue2axios请求拦截 依赖项 “vue”: “^2.6.11” “axios”: “^0.21.0” “element-ui”: “^2.13.2”(做弹窗提示&#xff0c;可以不用) http.js // 引入axi…...

Xshell连接阿里云服务器搭建网站

一、建设一个网站的基本要求 申请一个独立的域名申请一台云服务器ECS在服务器上安装网站环境&#xff0c;如&#xff1a;Apache发布网站内容至云服务器将第一步注册的域解析至云服务器的外网IP地址进行ICP备案 二、用户访问网站的过程 在浏览器上输入域名浏览器自动调用DNS&…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...

Python环境安装与虚拟环境配置详解

本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南&#xff0c;适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者&#xff0c;都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...

背包问题双雄:01 背包与完全背包详解(Java 实现)

一、背包问题概述 背包问题是动态规划领域的经典问题&#xff0c;其核心在于如何在有限容量的背包中选择物品&#xff0c;使得总价值最大化。根据物品选择规则的不同&#xff0c;主要分为两类&#xff1a; 01 背包&#xff1a;每件物品最多选 1 次&#xff08;选或不选&#…...

Docker、Wsl 打包迁移环境

电脑需要开启wsl2 可以使用wsl -v 查看当前的版本 wsl -v WSL 版本&#xff1a; 2.2.4.0 内核版本&#xff1a; 5.15.153.1-2 WSLg 版本&#xff1a; 1.0.61 MSRDC 版本&#xff1a; 1.2.5326 Direct3D 版本&#xff1a; 1.611.1-81528511 DXCore 版本&#xff1a; 10.0.2609…...

作为点的对象CenterNet论文阅读

摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表&#xff0c;并对每一个位置进行分类。这种做法既浪费又低效&#xff0c;并且需要额外的后处理。在本文中&#xff0c;我们采取了不同的方法。我们将物体建模为单…...