数据结构第八节:红黑树(初阶)

【本节要点】

  • 红黑树概念
  • 红黑树性质
  • 红黑树结点定义
  • 红黑树结构
  • 红黑树插入操作的分析

一、红黑树的概念与性质

1.1 红黑树的概念

红黑树 ,是一种 二叉搜索树 ,但 在每个结点上增加一个存储位表示结点的颜色,可以是 Red和 Black 。 通过对 任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路 径会比其他路径长出俩倍 ,因而是 接近平衡 的。
红黑树构造:[10(黑)] /        \[5(红)]     [20(黑)]/     \       /     \[3(黑)] [8(黑)] [15(红)] [25(红)]/  \    /  \     /  \    /  \NIL NIL  NIL NIL  NIL NIL NIL NIL

1.2 红黑树的性质 

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

 以上五点性质可以保证:其最长路径中节点个数不会超过最短路径节点个数的两倍。

 二、红黑树结点定义

// 结点的颜色
enum Colour
{RED,BLACK,
};// 红黑树结点的定义
template<class K, class V>
struct RBTreeNode
{pair<K, V> _kv;            // 结点的键值对RBTreeNode<K, V>* _left;   // 结点的左孩子RBTreeNode<K, V>* _right;  // 结点的右孩子RBTreeNode<K, V>* _parent; // 结点的双亲(红黑树需要旋转,为了实现简单所以给出该结点)Colour _col;               // 结点的颜色// 结点的构造函数RBTreeNode(const pair<K, V>& kv):_kv(kv), _left(nullptr), _right(nullptr), _parent(nullptr), _col(RED){}
};

注意:红黑树定义结点时,默认结点颜色为红色,这一设计选择直接增加红黑树的平衡维护效率和整体性能,大大减少时间复杂度。

三、红黑树的结构

// 以本数组为例
num[3, 5, 8, 10, 15, 20, 25]
红黑树构造:[10(黑)] /        \[5(红)]     [20(黑)]/     \       /     \[3(黑)] [8(黑)] [15(红)] [25(红)]/  \    /  \     /  \    /  \NIL NIL  NIL NIL  NIL NIL NIL NIL

图示说明

  1. 根结点标记:根结点 10 为黑色,符合性质2(根结点必黑)

  2. 红色结点规则:红色结点 51525 的子结点均为黑色,满足性质3(红色结点不连续)

  3. 黑高一致性验证:从根结点到任意 NIL 的路径黑色结点数均为 2

  4. NIL结点处理:所有叶子结点显式标记为 NIL(黑色),符合性质5

  5. 最长/最短路径对比

    路径类型示例路径结点数比例
    最短路径10→20→NIL21:1
    最长路径10→5→3→NIL31.5:1
    理论极限红黑交替路径(未出现)≤4≤2:1

 四、红黑树的插入操作

                              [开始插入新结点Z]│▼┌─────────执行标准BST插入─────────┐│                                │▼                                ▼[Z设为红色]                   [保持BST性质]│▼┌─────父结点P是否为红色?─────┐│                            │▼ (是)                       ▼ (否)[存在双红冲突需处理]               [插入完成]│▼┌────叔结点U的颜色?────┐│                      │▼ (红色)               ▼ (黑色/NIL)
[Case1: 颜色翻转]     [判断冲突结构类型]│                      │▼                      ├─────────────────────────┐
[将P、U设为黑色]           ▼                         ▼│               [Z-P-G呈三角型]            [Z-P-G呈直线型]▼                      │                         │
[将G设为红色]        [Case2: 旋转父结点]      [Case3: 旋转祖父结点]│                      │                         │▼                      ▼                         ▼
[以G为新Z向上回溯]   [转为直线型冲突]         [交换颜色并旋转]│▼[调整完成]│▼[最终确保根结点为黑]

4.1 基本BST插入阶段

  • 插入位置遵循二叉搜索树规则

  • 新结点初始颜色必须为红色(最小化规则破坏)

4.2 冲突检测阶段

  • 要素1:父结点状态判断
  • 要素2:叔结点颜色判定
  • 要素3:冲突结构类型识别

4.3  典型场景演练

场景1:叔结点为红(Case1)

         G(黑)                 G(红)/   \     颜色翻转     /   \P(红) U(红)  →       P(黑) U(黑)/                   /Z(红)              Z(红)

检测要点

  • 确认U存在且为红

  • 将冲突标记上移给G

  • 继续以G作为新Z向上检测

场景2:叔结点为黑-三角型(Case2)

     G(黑)            G(黑)/               /P(红)   →      Z(红)\           /Z(红)     P(红)

检测要点

  • 判断Z是P的右子结点

  • 识别为三角型冲突

  • 转换为直线型处理

场景3:叔结点为黑-直线型(Case3)

      G(黑)             P(黑)/               /   \P(红)   →      Z(红) G(红)/Z(红)

检测要点

  • 确认Z是P的左子结点

  • 直接触发祖父旋转

  • 完成颜色交换

 4.4 总结

冲突检测阶段通过三级条件筛选(父结点状态→叔结点颜色→冲突结构类型),将复杂的平衡问题分解为可控的局部操作。这种分层检测机制:

  1. 确保90%以上的插入操作只需1次检测即可完成
  2. 将最坏情况的时间复杂度严格控制在O(log n)
  3. 为后续的旋转/颜色调整提供精准的操作依据

该设计体现了红黑树"以检测换计算,以分类求高效"的核心优化思想,是其能在大规模数据场景下保持卓越性能的关键所在。


以上就是红黑树初阶知识的了解,接下来我会继续更新红黑树进阶红黑树的模拟实现、使用红黑树底层对map和set容器的模拟实现。制作不易,请大家多多点赞收藏啦!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot3.3.X整合Mybatis-Plus

前提说明&#xff1a; 项目的springboot版本为&#xff1a;3.3.2 需要整合的mybatis-plus版本&#xff1a;3.5.7 废话不多说&#xff0c;开始造吧 1.准备好数据库和表 2.配置全局文件application.properties或者是application.yml&#xff08;配置mapper的映射文件路径&am…

可视化图解算法:链表指定区间反转

1. 题目 描述 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例1 输入&#xff1a; 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输…

✨SQL-递归CTE

&#x1f4d6; SQL魔法课堂&#xff1a;CTE「时间折叠术」全解 &#x1f3a9; 第一章&#xff1a;什么是CTE&#xff1f; CTE&#xff08;Common Table Expression&#xff09; 就像 SQL 里的「临时笔记本」&#x1f4d2;&#xff1a; WITH 临时笔记本 AS ( SELECT ... FRO…

Cursor 新手入门使用教程

一、Cursor 是什么&#xff1f; Cursor 是一个集成了 GPT-4、Claude 3.5 等先进 LLM&#xff08;大语言模型&#xff09;的类 VSCode 编译器&#xff0c;可以理解为在 VSCode 中集成了 AI 辅助编程助手。从界面布局来看&#xff0c;Cursor 与 VSCode 基本一致&#xff0c;且使…

如何在Spring Boot中配置和使用MyBatis-Plus

在当今的Java开发中&#xff0c;Spring Boot已经成为了一个非常流行的框架&#xff0c;而MyBatis-Plus则是一个强大的ORM框架&#xff0c;为开发人员提供了更简便的数据库操作方式。很多开发者都在使用Spring Boot和MyBatis-Plus的组合来快速构建高效的应用。今天就来聊聊如何在…

【贪心算法3】

力扣1005.k次取反后最大化的数组和 链接: link 思路 既然要求最大和&#xff0c;那么不妨先给数组排个序&#xff0c;如果有负数&#xff0c;先处理负数从前往后给数组取反&#xff0c;如果负数处理完后k还有次数&#xff0c;此时数组全是正数了&#xff0c;只需要对第一个元…

自然语言处理中的语音识别技术:从声波到语义的智能解码

引言 语音识别&#xff08;Automatic Speech Recognition, ASR&#xff09;是自然语言处理&#xff08;NLP&#xff09;的关键分支&#xff0c;旨在将人类语音信号转化为可处理的文本信息。随着深度学习技术的突破&#xff0c;语音识别已从实验室走向日常生活&#xff0c;赋能…

1688店铺所有商品数据接口详解

​​一、接口概述淘宝开放平台提供 1688.items.onsale.get/taobao.item_search_shop 接口&#xff0c;可批量获取店铺在售商品列表&#xff0c;包含商品 ID、标题、价格、销量、图片等核心信息。该接口适用于商品库管理、竞品监控、数据分析等场景 ​二、接口调用流程 前期准…

ArduPilot开源代码之AP_OSD

ArduPilot开源代码之AP_OSD 1. 源由2. 简介3. 补丁4. 框架设计4.1 启动代码 (AP_OSD::init)4.2 任务代码 (AP_OSD::osd_thread)4.3 实例初始化 (AP_OSD::init_backend) 5. 重要例程5.1 AP_OSD::update_stats5.2 AP_OSD::update_current_screen5.3 AP_OSD::update_osd 6. 总结7.…

qt open3dAlpha重建

qt open3dAlpha重建 效果展示二、流程三、代码效果展示 二、流程 创建动作,链接到槽函数,并把动作放置菜单栏 参照前文 三、代码 1、槽函数实现 void on_actionAlpha_triggered();//alpha重建 void MainWindow::

Deepseek可以通过多种方式帮助CAD加速工作

自动化操作&#xff1a;通过Deepseek的AI能力&#xff0c;可以编写脚本来自动化重复性任务。例如&#xff0c;使用Python脚本调用Deepseek API&#xff0c;在CAD中实现自动化操作。 插件开发&#xff1a;结合Deepseek进行二次开发&#xff0c;可以创建自定义的CAD插件。例如&a…

Centos的ElasticSearch安装教程

由于我们是用于校园学习&#xff0c;所以最好是关闭防火墙 systemctl stop firewalld systemctl disable firewalld 个人喜欢安装在opt临时目录&#xff0c;大家可以随意 在opt目录下创建一个es-standonely-docker目录 mkdir es-standonely-docker 进入目录编辑yml文件 se…

c++ 调用 gurobi 库,cmake,mac

gurobi 一般使用 python 调用&#xff0c;官方的培训会议及资料大部分也都基于 python。 由于最近上手了 c&#xff0c;因此想试试 c 怎么调用 gurobi。但我发现&#xff0c;c 调用第三方库比 python 或 java 要复杂不少。python 中直接 import 第三方库&#xff0c;java 加载…

Python基于Django的医用耗材网上申领系统【附源码、文档说明】

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

Python中很常用的100个函数整理

Python 内置函数提供了强大的工具&#xff0c;涵盖数据处理、数学运算、迭代控制、类型转换等。本文总结了 100 个常用内置函数&#xff0c;并配备示例代码&#xff0c;提高编程效率。 1. abs() 取绝对值 print(abs(-10)) # 10 2. all() 判断所有元素是否为真 print(all([…

Python毕业设计选题:基于django+vue的疫情数据可视化分析系统

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 员工管理 疫情信息管理 检测预约管理 检测结果…

C#程序结构及基本组成说明

C# 程序的结构主要由以下几个部分组成,以下是对其结构的详细说明和示例: 1. 基本组成部分 命名空间 (Namespace) 用于组织代码,避免命名冲突。通过 using 引入其他命名空间。 using System; // 引入 System 命名空间类 (Class) C# 是面向对象的语言,所有代码必须定义在类或…

Python 编程题 第八节:字符串变形、压缩字符串、三个数的最大乘积、判定字符是否唯一、IP地址转换

字符串变形 swapcase()方法将字符串大小写转换&#xff1b;split()方法将字符串以括号内的符号分隔并以列表形式返回 sinput() ls.split(" ") ll[::-1] s"" for i in l:ai.swapcase()sas" " print(s[0:len(s)-1]) 压缩字符串 很巧妙的方法 …

大语言模型学习--向量数据库基础知识

1.向量 向量是多维数据空间中的一个坐标点。 向量类型 图像向量 文本向量 语音向量 Embedding 非结构化数据转换为向量过程 通过深度学习训练&#xff0c;将真实世界离散数据&#xff0c;投影到高维数据空间上&#xff0c;通过数据在空间中间的距离体现真实世界的相似度 V…

项目工坊 | Python驱动淘宝信息爬虫

目录 前言 1 完整代码 2 代码解读 2.1 导入模块 2.2 定义 TaoBao 类 2.3 search_infor_price_from_web 方法 2.3.1 获取下载路径 2.3.2 设置浏览器选项 2.3.3 反爬虫处理 2.3.4 启动浏览器 2.3.5 修改浏览器属性 2.3.6 设置下载行为 2.3.7 打开淘宝登录页面 2.3.…