红黑树解密:为什么根节点必须是黑色,两个红色节点不能挨着?

news2024/9/24 15:27:37

红黑树解密:为什么根节点必须是黑色,两个红色节点不能挨着?

  • 博主简介
  • 一、引言
    • 1.1、红黑树是什么及其特点
    • 1.2、根节点为黑色和红色节点不连续的性质介绍
  • 二、为何根节点必须是黑色?
  • 三、为何两个红色节点不能挨着?
  • 总结

博主简介


💡一个热爱分享高性能服务器后台开发知识的博主,目标是通过理论与代码实践的结合,让世界上看似难以掌握的技术变得易于理解与掌握。技能涵盖了多个领域,包括C/C++、Linux、Nginx、MySQL、Redis、fastdfs、kafka、Docker、TCP/IP、协程、DPDK等。
👉
🎖️ CSDN实力新星、CSDN博客专家、华为云云享专家
👉
👉我的博客将提供以下内容:
👉
💡1. 高性能服务器后台开发知识深入剖析:深入探讨各种技术的原理和内部工作机制,帮助理解它们的核心概念和使用方法。
👉
💡2. 实践案例与代码分享:分享一些实际项目中的应用案例和代码实现,帮助将理论知识转化为实际应用,并提供实践中的经验和技巧。
👉
💡3. 技术教程和指南:编写简明扼要的教程和指南,帮助初学者入门并逐步掌握这些技术,同时也为有经验的开发者提供深入的技术进阶指导。
👉
💡无论是一个刚入门的初学者,还是一个有经验的开发者,我的博客都将提供有价值的内容和实用的技术指导。


一、引言

通过解释为什么根节点必须是黑色,并探讨为何两个红色节点不能相邻,来详细解密红黑树的特性和原理。文章将提供实例和图解来帮助读者更好地理解这些概念,并最终总结根节点黑色和红色节点分离的重要性。

1.1、红黑树是什么及其特点

红黑树是一种自平衡的二叉查找树,它在每个节点上增加了一个额外的属性表示节点的颜色,可以是红色或黑色。

1
2
3
4
5
6
7
8
9
header
nil
nil
nil
nil
nil
// 定义红黑树节点颜色
enum Color {
    RED,
    BLACK
};

// 定义红黑树节点
typedef struct Node {
    int key;
    enum Color color;
    struct Node *parent;
    struct Node *left;
    struct Node *right;
} Node;

// 定义红黑树
typedef struct RedBlackTree {
    Node *root;
    Node *nil;
} RedBlackTree;

红黑树具有以下特点:

  1. 根节点必须是黑色:红黑树的根节点必须是黑色,这是为了保持红黑树的平衡性和性质。

  2. 所有叶子节点(空节点)都是黑色:红黑树的叶子节点都被认为是黑色,而不是使用普通的空节点。这样做是为了简化插入和删除操作的处理。

  3. 红色节点的子节点必须是黑色:如果一个节点是红色,则它的两个子节点必须是黑色。这个特性确保了没有连续的红色节点出现,从而维持了红黑树的平衡性。

  4. 从根到叶子节点的每条路径上,黑色节点数量相同:任意一条从根节点到叶子节点的路径上,经过的黑色节点数量必须相同。这个特点保证了红黑树的高度是平衡的,从而提供了较快的查找、插入和删除操作。

  5. 任意节点到其每个叶子的所有简单路径都包含相同数量的黑色节点:对于每个节点来说,它到其所有后代叶子节点的路径上都包含相同数量的黑色节点。这个特点进一步确保了红黑树的平衡性和性质。

通过维持这些特点,红黑树能够在动态更新的过程中自动调整并保持平衡,从而保证了较高的查找效率和稳定的性能。红黑树被广泛应用于各种数据结构和算法中,比如在操作系统中用于管理文件系统的索引,以及在编译器中用于优化代码生成等。

1.2、根节点为黑色和红色节点不连续的性质介绍

根节点为黑色和红色节点不连续是红黑树的两个基本性质,它们对于红黑树的平衡性和性质的维持起着重要作用。

  1. 根节点为黑色:红黑树的第2条性质规定根节点必须是黑色。这是为了确保红黑树的平衡性。如果根节点是红色,那么可以通过将其重新着色为黑色来满足此性质。根节点的颜色定义为黑色,可以确保从根到叶子节点的每条路径上都有相同数量的黑色节点,从而保持红黑树的高度平衡,提供较快的查找、插入和删除操作。

  2. 红色节点不连续:红黑树的第4条性质规定红色节点的子节点必须是黑色。这意味着在红黑树中,没有两个相邻的红色节点,它们之间必须至少存在一个黑色节点。这个性质的目的是避免出现红色节点连续的情况下引发的不平衡问题。如果连续的红色节点出现,会导致路径上的黑色节点数量减少,破坏了红黑树的性质和平衡性。因此,红色节点必须与黑色节点交替出现,以保持红黑树的平衡。

通过根节点为黑色和红色节点不连续这两个性质,红黑树能够自动调整并保持平衡,从而提供高效的查找、插入和删除操作。这些性质确保了红黑树在动态更新的过程中保持了平衡性,并且能够维持相对稳定的性能。

二、为何根节点必须是黑色?

红黑树有一条性质规定根节点必须是黑色。这一性质的存在是为了确保红黑树的平衡性和性质的维持。

首先,根节点为黑色可以保证从根节点到每个叶子节点的路径上有相同数量的黑色节点。这是因为根节点没有父节点,所以不会有父节点为红色的情况,也就不需要考虑父节点对路径中的黑色节点数量的影响。而其他节点的颜色可能是红色或黑色,但它们都有一个指向父节点的指针,所以它们的父节点是黑色的话,路径上的黑色节点数量就不会改变。

其次,根节点为黑色可以确保红黑树的高度平衡。由于红黑树的性质要求从根到每个叶子节点的路径上有相同数量的黑色节点,那么任意一条路径的最长长度就是从根节点到叶子节点的路径。如果根节点是红色的,那么在所有路径中,从根节点到叶子节点的路径长度将比其他路径长1,这将导致树的高度不平衡,使得插入、删除和查找操作的效率下降。

因此,根节点必须是黑色的约束条件保证了红黑树的平衡性和性质的维持。通过这一性质,红黑树能够自动调整并保持平衡,在动态更新的过程中提供了较快的插入、删除和查找操作效率。

根节点黑色的作用和意义:

  • 通过将根节点设置为黑色,红黑树能够保持一定的平衡性。红黑树的平衡是通过对节点进行染色和旋转操作来实现的,而根节点的黑色可以确保在进行这些操作时不会破坏红黑树的平衡性。
  • 根节点黑色还是红黑树约束规则的一部分。根据红黑树的定义,每个节点要么是红色,要么是黑色,而根节点必须为黑色。这个约束规则是为了确保红黑树具有较好的性质,例如黑高度相等、从任意节点到其所有后代叶子节点的路径上的黑色节点数量相等等。
  • 根节点黑色的设定可以简化一些红黑树操作的实现。例如,在插入和删除节点时,需要对红黑树进行平衡调整,而根节点黑色的存在可以减少一些特殊情况的处理,使得操作更加简洁和高效。

当根节点为红色时,可能会违反红黑树的平衡性质。

考虑以下红黑树示例:

2
5
7
10
12
15
20
header
nil
nil
nil
nil

在这个示例中,根节点10是黑色的。现在尝试将根节点设为红色,看看会发生什么变化。

假设将根节点10改为红色,得到以下红黑树:

2
5
7
10
12
15
20
header
nil
nil
nil
nil

现在来看看,如果执行删除操作(例如删除节点2),会导致什么问题。

(1)首先,需要从根节点开始向下找到待删除的节点,并删除它。在这种情况下,需要删除节点2。

5
7
10
12
15
20
header
nil
nil
nil
nil

(2)接下来,需要对树进行平衡调整,以确保它仍然符合红黑树的性质。根据红黑树调整规则,当删除一个节点时,会有以下几种情况需要处理:

  • 如果删除的节点是红色的,不会影响树的平衡性质。

  • 如果删除的节点是黑色的,并且它的子节点中有一个红色节点,可以将红色节点转换为黑色节点,以保持平衡。

  • 如果删除的节点是黑色的,并且它的子节点都是黑色的,这就违反了红黑树的性质。此时,需要进行进一步的平衡调整。

在这个例子中,删除的节点2是黑色的,并且它的兄弟节点7也是黑色的,违反了第3种情况。从而出现黑色节点高度不是一致的情况(10–>5–>nil的黑高是2,而其他分支的黑高是3)。

如果根节点是黑色的,可以通过变换和旋转操作来重新平衡树,使其满足红黑树的性质。 就如下面所示:

5
7
10
12
15
20
header
nil
nil
nil
nil

但是,如果根节点是红色的,无法通过简单的旋转和变换来修复树的平衡性(无论如何旋转都无法满足红黑树的性质了)。这是因为改变根节点的颜色可能会导致其他节点的性质出现问题,从而破坏整个树的平衡性。

因此,根节点必须是黑色的,以确保树始终保持平衡,并且能够进行简单有效的平衡调整。

三、为何两个红色节点不能挨着?

在红黑树中,每个节点可以被标记为红色或者黑色。有一条性质要求如果一个节点是红色的,则它的子节点必须是黑色的。

这个性质的目的是确保红黑树中没有连续的红色节点。如果出现了连续的红色节点,就会导致路径上的黑色节点数目不平衡,违反了红黑树的其他性质。

通过限制红色节点的子节点必须是黑色,红黑树可以保持平衡,从而提供了较好的性能。因为红黑树的高度是 l o g ( N ) log(N) log(N),其中N是节点的数量,这使得查找、插入和删除等操作具有较好的时间复杂度。

如果存在连续的红色节点,可能导致以下问题:

  • 违反平衡性:红黑树的平衡性是通过调整红色节点和黑色节点的位置来实现的。如果存在连续的红色节点,就需要进行额外的调整操作来恢复树的平衡性。这可能导致树的高度增加,使得树的查找、插入和删除等操作的效率降低。

  • 破坏性能:红黑树的主要优势在于其平衡性,可以保证最坏情况下的时间复杂度为 O ( l o g n ) O(log n) O(logn)。但如果存在连续的红色节点,树的平衡性将被破坏,可能导致某些操作的时间复杂度变为 O ( n ) O(n) O(n),使得性能大大下降。

  • 遗漏插入点:红黑树在插入新节点时,通常会通过旋转操作来调整树的结构。如果存在连续的红色节点,插入新节点时可能无法正确找到插入点,导致插入失败或产生错误的结果。

因此,连续红色节点是红黑树中需要避免的问题,违反了红黑树的平衡性和规则。在实现红黑树时,需要进行相应的检查和调整,以确保没有连续的红色节点出现。

举个例子来说明为何两个红色节点不能挨着。
假设存在如下的红黑树:

2
5
7
10
12
15
20
header
nil
nil
nil
nil

这是一个正常的红黑树,当我们把它改变成连续红色节点的红黑树会怎么样?我们可以构造出一个不平衡的红黑树,如下所示:

2
5
7
10
12
15
20
header
nil
nil
nil
nil

此时是不满足《从根到叶子节点的每条路径上,黑色节点数量相同》这个红黑树性质的,在某些路径上就会出现过多的黑色节点,导致不平衡。所以为了保证红黑树的性质,就需要改变,从而出现如下的红黑树形状:

2
5
7
10
12
15
20
header
nil
nil
nil

这样的情况下,两个红色节点挨着,这使得从根节点到叶子节点的路径上,左侧的分支多出一个节点。这样的不平衡会导致某些操作的时间复杂度增加,例如插入和删除操作。

因此,为了保持红黑树的性质和平衡性,两个红色节点不能挨着,父节点和子节点不能同时为红色。

总结

红黑树是一种自平衡的二叉搜索树,它具有以下重要性质:

  • 根节点为黑色:保证了根节点不会为红色,这样可以确保从根节点到每个叶子节点的路径长度相等。

  • 红色节点不连续:保证了任意一条路径上不会有两个连续的红色节点,这样可以确保树的高度较小,提高了查找、插入和删除操作的效率。

红黑树的平衡性与上述性质密不可分。通过保持根节点为黑色和红色节点不连续,红黑树能够在动态插入和删除操作时进行自平衡,使得整个树的高度保持较小。由于红黑树的高度与节点数量之间的关系是log(n),其中n为节点数量,所以红黑树能够在大规模数据集上表现出优秀的性能。

总结起来,保持根节点为黑色和红色节点不连续是红黑树实现自平衡的关键,这些性质相互依赖,共同确保了红黑树的高度较小,从而提高了其查找、插入和删除操作的效率。

在这里插入图片描述

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

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

相关文章

PCB绘制时踩的坑 - SOT-223封装

SOT-223封装并不是同一的,细分的话可以分为两种常用的封装。尤其是tab脚的属性很容易搞错。如果你想着用tab脚连接有属性的铺铜,来提高散热效率,那么你一定要注意你购买的器件tab脚的属性。 第一种如下图,第1脚为GND,第…

Packet Tracer - 备份配置文件

Packet Tracer - 备份配置文件 目标 第 1 部分:与 TFTP 服务器建立连接 第 2 部分:从 TFTP 服务器传输配置 第 3 部分:将配置和 IOS 备份到 TFTP 服务器上 拓扑图 背景/场景 本练习旨在展示如何从备份恢复配置,然后执行新的…

Stephen Wolfram:神经网络

Neural Nets 神经网络 OK, so how do our typical models for tasks like image recognition actually work? The most popular—and successful—current approach uses neural nets. Invented—in a form remarkably close to their use today—in the 1940s, neural nets …

如何查找网页的cookie【以两步路平台】

登录/注册账号【重要】 进入开发人员工具 刷新页面,发现“全部”对应的列表发生改变 找到列表首页的文本后缀.htm的信息,点开后查找网站的Cookie。 注意:Cookie必须在登陆后的才有效,并且每次爬取都需要重新查找更新Cookie&…

六、初始化和清理(1)

本章概要 利用构造器保证初始化方法重载 区分重载方法重载与基本类型返回值的重载无参构造器 this 关键字在构造器中调用构造器static 的含义 利用构造器保证初始化 "不安全"的编程是造成编程代价昂贵的罪魁祸首之一。有两个安全性问题:初始化和清理。…

redis和数据库双写不一致一般如何解决-面试

先介绍一下常规的几种做法 1、先删缓存,在改数据库 2、先改数据库,在删缓存 3、先改数据库,在改缓存 4、延迟双删(先删缓存,再改数据库,延迟几百毫秒,再删缓存),此方…

通过gre隧道建立私有专用网络

Internet 配置 vlan 128 vlan 202 router1: router2: router1 ping router 2

一起学SF框架系列5.11-spring-beans-数据校验validation

在日常的项目开发中,应用在执行业务逻辑之前,为了防止非法参数对业务造成的影响,必须通过校验保证传入数据是合法正确的,但很多时候同样的校验出现了多次,在不同的层,不同的方法上,导致代码冗余…

map求和accumulate、参数互换

运行代码&#xff1a; //map求和accumulate、参数互换 #include"std_lib_facilities.h"istream& operator>>(istream& is, map<string, int>&mm) {string ss"";int ii0;is >> ss;if(is>>ii)mm[ss] ii;return is; }t…

VSCode中python代码输出中文乱码解决

前言 最近在vs code里面执行python脚本时&#xff0c;只有打印中文&#xff0c;就会乱码。 内容 先检查右下角编码集设置是否正确 检查右下角编码集设置是否正确 &#xff1a; 如果不是utf-8点击修改。 如果还是不行&#xff0c;就进行下面的操作 修改用户设置 路径&a…

【算法基础:动态规划】5.1 背包问题

文章目录 01背包例题&#xff1a;2. 01背包问题 完全背包例题&#xff1a;3. 完全背包问题 多重背包例题&#xff1a;4. 多重背包问题 I例题&#xff1a;5. 多重背包问题 II&#xff08;数据范围较大&#xff1a;二进制优化&#xff09; 分组背包例题&#xff1a;9. 分组背包问…

2023/7/29总结

项目&#xff1a; 这几天主要实现了评论的功能点: 还是有点小bug&#xff0c;还在更改中…… 修改个人中心的界面 接下来是把收藏完善&#xff0c;因为收藏需要用户自己创建一个新的收藏夹

iOS开发-转场动画切换界面(类似系统动画)

iOS开发-转场动画切换界面&#xff08;类似系统动画&#xff09; 在开发中&#xff0c;无论我们使用 push 还是 present 推出新的 viewcontroller 时&#xff0c;系统为了提高用户体验都会为我们默认加上一些过渡动画。但是开发中需要自定义过度动画效果。这里就需要用到了转场…

二十五章:用于弱监督语义分割的激活调节和重新校准方案

0.摘要 图像级弱监督语义分割&#xff08;WSSS&#xff09;是一项基础而具有挑战性的计算机视觉任务&#xff0c;有助于场景理解和自动驾驶。大多数现有方法利用基于分类的类激活图&#xff08;CAMs&#xff09;作为初始伪标签&#xff0c;但这些方法往往关注区分性的图像区域&…

Leetcode刷题---C语言实现初阶数据结构---单链表

1 删除链表中等于给定值 val 的所有节点 删除链表中等于给定值 val 的所有节点 给你一个链表的头节点head和一个整数val&#xff0c;请你删除链表中所有满足Node.valval的节点&#xff0c;并返回新的头节点 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[…

Tomcat 的使用(图文教学)

Tomcat 的使用&#xff08;图文教学&#xff09; 前言一、什么是Tomcat&#xff1f;二、Tomcat 服务器和 Servlet 版本的对应关系三、Tomcat 的使用1、安装2、目录介绍3、如何启动4、Tomcat 的停止5、如何修改 Tomcat 的端口号6、如何部暑 web 工程到 Tomcat 中6.1 方式一6.2 …

建设银行秋招指南,备考技巧和考试内容详解

建设银行秋招简介 银行作为非常吃香的岗位&#xff0c;每年都有不少同学通过投递简历&#xff0c;进入笔试&#xff0c;再到面试成功&#xff0c;成功到银行就职&#xff0c;也有相当一部分同学因为信息差&#xff0c;符合条件却没有报名。无法进入银行工作。 建设银行的秋招…

从保存受限的手机APP中提取文件(读取Android系统中的新增缓存文件)

这个手机APP的权限可能设置了无法在应用内保存文件&#xff0c;但是这个文件实际上一定存在于本地的某个地方&#xff0c;本文的方法通过遍历最后修改日期在今天的文件&#xff0c;很容易就可以找到它。 首先安装一个QPython&#xff0c;这个软件可以允许你在安卓手机上运行Py…

Linux常用命令——dpkg-reconfigure命令

在线Linux命令查询工具 dpkg-reconfigure Debian Linux中重新配制一个已经安装的软件包 补充说明 dpkg-reconfigure命令是Debian Linux中重新配置已经安装过的软件包&#xff0c;可以将一个或者多个已安装的软件包传递给此指令&#xff0c;它将询问软件初次安装后的配置问题…

平板光波导中导模的(注意不是泄露模)传播常数β的matlab计算(验证了是对的)

参照的是导波光学_王建(清华大学)的公式(3-1-2、3-1-3)&#xff0c;算的参数是这本书的图3-3的。 function []PropagationConstantsMain() clear;clc;close all lambda01.55;%真空或空气中的入射波长&#xff0c;单位um k02*pi/lambda0; m3;%导模阶数(需要人为指定) n11.62;%芯…