红黑树原理简单解析

article/2025/11/3 23:40:45

一、红黑树为什么会出现呢?

是因为二叉搜索树有可能会出现极端的情况,就是只有一侧有数据,那这样的话就会降级为链表。后来出现了平衡二叉树,但是由于强制平衡所导致付出的代价比较高昂,所以黑红树出现了。

二、简介

红黑树(Red Black Tree) 的实现是基于二叉查找树的,对于含有n个节点的二叉查找树的最坏的情况是这n个节点形成一条单链,此时二叉查找树的高度为n,时间复杂度为O(n)。为了维持O(lg n)的运行时间,就需要采取一些措施在不影响二叉查找树的性质下改变二叉查找树的结构,使之平衡。红黑树就是这样一种二叉查找树,即自平衡二叉查找树。

三、特征

红黑树是每个节点都带有颜色属性的二叉查找树,颜色为红色或黑色。
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3. 所有叶子都是黑色。(叶子是NUIL节点)
性质4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

在这里插入图片描述

四、代码

然后我们看一下节点的定义

public class RBTNode<T extends Comparable<T>> {boolean color;        // 颜色T key;                // 关键字(键值)RBTNode<T> left;    // 左孩子RBTNode<T> right;    // 右孩子RBTNode<T> parent;    // 父结点public RBTNode(T key, boolean color, RBTNode<T> parent, RBTNode<T> left, RBTNode<T> right) {this.key = key;this.color = color;this.parent = parent;this.left = left;this.right = right;}}

当对红黑树进行插入或删除时,就有可能破坏红黑树的性质,这时需要通过变色、左旋与右旋操作平衡红黑树。变色操作很简单,红变黑,黑变红,就不仔细介绍了,下面介绍左旋与右旋

  1. 左旋
    在这里插入图片描述
    此图是以X为旋转结点

定义:以某个结点作为支点(旋转结点),其右子结点变为旋转结点的父结点,右子结点的左子结点变为旋转结点的右子结点,左子结点保持不变。

/* 1. 对红黑树的节点(x)进行左旋转2.  3. 左旋示意图(对节点x进行左旋):4.      px                              px5.     /                               /6.    x                               y                7.   /  \      --(左旋)-.           / \                #8.  lx   y                          x  ry     9.     /   \                       /  \10.    ly   ry                     lx  ly  11.  12.  */
private void leftRotate(RBTNode<T> x) {// 设置x的右孩子为yRBTNode<T> y = x.right;// 将 “y的左孩子” 设为 “x的右孩子”;// 如果y的左孩子非空,将 “x” 设为 “y的左孩子的父亲”x.right = y.left;if (y.left != null)y.left.parent = x;// 将 “x的父亲” 设为 “y的父亲”y.parent = x.parent;if (x.parent == null) {this.mRoot = y;            // 如果 “x的父亲” 是空节点,则将y设为根节点} else {if (x.parent.left == x)x.parent.left = y;    // 如果 x是它父节点的左孩子,则将y设为“x的父节点的左孩子”elsex.parent.right = y;    // 如果 x是它父节点的左孩子,则将y设为“x的父节点的左孩子”}// 将 “x” 设为 “y的左孩子”y.left = x;// 将 “x的父节点” 设为 “y”x.parent = y;
}
  1. 右旋
    在这里插入图片描述
    此图是以Y结点为旋转结点

定义:以某个结点作为支点(旋转结点),其左子结点变为旋转结点的父结点,左子结点的右子结点变为旋转结点的左子结点,右子结点保持不变。

/* * 对红黑树的节点(y)进行右旋转** 右旋示意图(对节点y进行左旋):*            py                               py*           /                                /*          y                                x                  *         /  \      --(右旋)-.            /  \                     #*        x   ry                           lx   y  *       / \                                   / \                   #*      lx  rx                                rx  ry* */
private void rightRotate(RBTNode<T> y) {// 设置x是当前节点的左孩子。RBTNode<T> x = y.left;// 将 “x的右孩子” 设为 “y的左孩子”;// 如果"x的右孩子"不为空的话,将 “y” 设为 “x的右孩子的父亲”y.left = x.right;if (x.right != null)x.right.parent = y;// 将 “y的父亲” 设为 “x的父亲”x.parent = y.parent;if (y.parent == null) {this.mRoot = x;            // 如果 “y的父亲” 是空节点,则将x设为根节点} else {if (y == y.parent.right)y.parent.right = x;    // 如果 y是它父节点的右孩子,则将x设为“y的父节点的右孩子”elsey.parent.left = x;    // (y是它父节点的左孩子) 将x设为“x的父节点的左孩子”}// 将 “y” 设为 “x的右孩子”x.right = y;// 将 “y的父节点” 设为 “x”y.parent = x;
}

五、插入情况分析

红黑树的插入和搜索二叉树一样,都需要先找到其插入位置。
插入的节点默认是红色。(要是黑色的话,那所有性质都一直满足,皆大欢喜了,就不用再平衡了,肯定不对)
然后再通过变色、左旋、右旋等满足其性质。
在这里插入图片描述

在这里插入图片描述

1. 被插入的节点是根节点。
处理方法:直接把此节点涂为黑色。

2. 被插入的节点的父节点是黑色。
处理方法:什么也不需要做。节点被插入后,仍然满足红黑树性质。

3. 被插入的节点的父节点是红色。
处理方法:这种情况下有连续两个红色节点,不满足红黑树的性质,需要调整。简单分析一下,被插入节点的父节点是红色,那么其祖父节点肯定存在且一定是黑色。我们依据其叔叔节点(其父亲节点的兄弟节点)的情况,将这种情况进一步划分。

3.1 叔叔结点为红色
我们可以将父亲结点p和叔叔结点s变黑色,祖父结点变红色就能解决问题。但是只是局部的平衡,祖父结点变红色还可能引起不平衡,因此还需要将祖父结点pp作为插入结点继续向上的平衡。(如果pp的父节点为空则直接把pp变黑色)

  • 把祖父结点pp变红色
  • 把父结点p和叔叔结点变黑色
  • 把pp作为新的插入结点
    在这里插入图片描述
    3.2 插入结点的父结点p是祖父结点pp的左子结点,插入结点的叔叔结点s不存在或为黑色
    这里可能会有疑问:既然父结点为红,为什么叔叔结点会为黑色,这样叔叔结点所在子树的黑色结点数目不就多一了吗?
    答:因为类似于上述3.1向上平衡的情况,因此插入结点的叔叔结点有可能是黑色的。

这种情况意味着左边子树结点比右边少,我们就需要通过右旋向右子树去借节点。

3.2.1 插入结点是父结点p的左子结点
因为把pp右旋后是黑色破坏了黑色结点的数量,因此还需要将pp变红。p则需要变为原来pp的颜色,即黑色。

  • 对pp右旋
  • p变黑,pp变红
    在这里插入图片描述

3.2.2 插入结点是父结点p的右子结点
这种情况我们发现对插入结点的父结点p进行左旋,就变成情况3.2.1了,然后按照3.2.1进行处理

  • 对p左旋

  • 转到情况3.2.1处理
    在这里插入图片描述
    3.3 插入结点的父结点p是祖父结点pp的右子结点,插入结点的叔叔结点s不存在或为黑色
    这种情况就是3.2情况的对称情况,这里有一个小技巧,把3.2的情况的左右对换就是3.3情况了

    3.3.1插入结点是父结点p的右子结点
    这种情况和3.2.1类似,因为是对称的,只要把左变成右,右变成左就行了。

  • 对pp左旋

  • p变黑,pp变红
    在这里插入图片描述
    3.3.2插入结点是父结点p的左子结点
    这种情况是和3.2.2类似,我们对p右旋,转为情况3.3.1

  • 对p右旋

  • 转到情况3.3.1处理
    在这里插入图片描述
    代码就不贴出来了,有兴趣大家可以看 jdk8 HashMap的源码

参考文章:
https://blog.csdn.net/qq_21989927/article/details/110846246
https://blog.csdn.net/weixin_45685353/article/details/105912742


http://chatgpt.dhexx.cn/article/WBvnlt5q.shtml

相关文章

laravel框架的下载与安装

首先我们先访问这个网址https://github.com/laravel/laravel 可以使用git克隆 或者直接下载安装包到自己的www目录下解压&#xff0c;此时访问localhost下的laravel目录&#xff0c; 此时会报没有vendor文件夹的一个错&#xff0c; 如果你已经下载了composer 在该文件夹目录下…

Laravel

Laravel的安装 1.确认composer已经安装 2.配置homestead.yaml文件sites&#xff1a;- map: laravel.xyz//域名配置to: /home/vagrant/code/laravel/public//入口文件路径 databases&#xff1a;//数据库- laravel 3.用秘钥登录homestead 4.更换中国镜像&#xff1a; composer…

Laravel下载文件及文档

2019独角兽企业重金招聘Python工程师标准>>> Laravel学院提供的相关资源下载 中文文档 Laravel 5.6 中文文档&#xff1a;PDF&#xff08;兼容 5.5 文档&#xff09; Laravel 5.3 中文文档&#xff1a;CHM | PDF Laravel 5.2 中文文档&#xff1a;CHM | PDF Laravel…

Laravel-admin的安装步骤

1、先确保是否安装composer&#xff0c;laravel及其版本并切换到阿里镜像 composer -v 查看composer的版本 php artisan 查看laravel的版本 扩展说明下&#xff1a;如果已经安装好composer&#xff0c;也可以通过 Composer 安装 Laravel 安装器 命令如下&#xff1a;composer…

如何正确的下载安装使用别人的laravel项目?

转载的,写的很简洁明了,白俊瑶博客 laravel 作为最流行的 php 框架&#xff1b;自然少不了很多基于 laravel 开发的项目&#xff1b;不过很多项目因为还处于开发中&#xff1b;或者其他原因并没有写安装文档&#xff1b;举个反面栗子&#xff1b;比如说我的 laravel-bjyadmin ;…

laravel 5.0

1.应用场景 使用PHP5.4[因为php5.4只能最高支持laravel 5.0]快速开发/维护一个web系统 2.学习/操作 1.获取参数 get方式 【查询字符串方式&#xff1a;Query String】 http://test.oa.com/api/u2d/texture/export?nametest&sex男 Route::get(export, U2dTextureControll…

Laravel最新版的安装(图文)

本文只适合刚接触或者想学Laravel的小白&#xff0c;老鸟就自动略过吧。 Laravel是一套简洁、优雅的PHP WEB开发框架&#xff08;PHP Web Framework&#xff09;&#xff0c;具有富于表达性且简洁的语法&#xff0c;Laravel是易于理解且强大的&#xff0c;它提供了强大的工具用…

Laravel 安装

工作需要&#xff0c;得学习一个php的后台admin管理框架&#xff0c;用于管理内容。这一天都在搜GitHub和gitee&#xff0c;GitHub是真的难访问啊&#xff0c;时断时续的&#xff1b;gitee上有一些&#xff0c;但好多都停更了的样子&#xff0c;有一些还不错的&#xff0c;例如…

Laravel 8 文件的上传/下载/显示的实例

如何实现对文件的操作&#xff0c;实现上传&#xff0c;下载&#xff0c;展示等等功能&#xff0c;我们通过编写一个简单的实例来了解其中具体的内容。 文件列表的展示/文件上传/文件下载 首先我们需要创建两个文件&#xff0c;一个视图文件&#xff0c;一个控制器&#xff0c…

安装laravel

安装laravel之前首先应该设置好安装好php&#xff0c;配置好环境变量。之后安装好compser。 1、安装php环境变量。 我使用的php环境安装包是upupw&#xff0c;&#xff08;php环境安装包有很多&#xff0c;例如phpstudy&#xff0c;wamp等等&#xff0c;读者可自行百度。&…

Laravel框架 -- 文件下载功能

Laravel 文件下载功能&#xff0c;通过手册&#xff0c;我们可以发现&#xff0c;Response的download方法就是我们所需要的文件下载功能的重要元素。 首先&#xff0c;我们注意一下&#xff0c;上面的方法中有两种写法&#xff0c;那么我以第二种为例子&#xff0c;解释一下实际…

laravel安装

文章目录 前言一、下载composer二、安装composercmd 输入composer 检验 三、配置镜像第一步第二步 四、虚拟目录配置 前言 前提&#xff1a;安装了phpStudy套件。https://www.xp.cn/download.html 一、下载composer 从laravel5.x 开始 , 官网https://getcomposer.org/Compose…

laravel文件上传与下载

https://github.com/Chumper/Zippergithub地址 composer require chumper/zipper看到这个代表安装成功 代表路由 . . . // package chumper/zipper Route::get(zip, ZipControllerindex)->name(zip.index); Route::post(zip/download, ZipControllerdownload)->name(zi…

Laravel 5.7下载、安装

本地安装laravel&#xff0c;php环境要配置好&#xff0c;推荐xmapp一键搭建。 1、程序包直接从官方下载&#xff0c;官方开源地址:https://github.com/laravel/laravel(当然也可从此网站&#xff1a;http://www.golaravel.com/download/ 下载一键安装包&#xff0c;下载下来就…

【laravel】laravel的下载安装

下载 Laravel Laravel 利用 Composer&#xff08;Composer 中文&#xff09;来管理其自身的依赖包。因此&#xff0c;在使用 Laravel 之前&#xff0c;请务必确保在你的机器上已经安装了 Composer 。 上面是laravel中文对于如何安装使用laravel的官方解释&#xff0c;不同于大多…

IE浏览器不能访问其他浏览器能正常访问

IE浏览器不能访问 而其他浏览器能正常访问 解决方法 -重置 1 win x 键&#xff0c;然后点击 windows powerShell &#xff08;以管理员方式运行&#xff09; 2 输入下面2条命令&#xff0c;记得回车 Netsh winsock resetnetsh advfirewall reset如下图所示&#xff1a; 运行…

浏览器访问Linux的Tomcat

浏览器访问Linux的Tomcat 1、在Linux下启动tomcat服务器 2、打开防火墙&#xff0c;开放8080端口

浏览器访问网页流程

从我们输入URL并按下回车键到看到网页结果之间发生了什么&#xff1f;换句话说&#xff0c;一张网页&#xff0c;要经历怎样的过程&#xff0c;才能抵达用户面前&#xff1f;下面来从一些细节上面尝试一下探寻里面的秘密。 前言&#xff1a;键盘与硬件中断 说到输入URL&#…

浏览器HTTPS访问问题

1、问题描述 搭建了HTTPS服务环境 https://172.16.0.17 &#xff0c;用浏览器访问时&#xff0c;出现提示信息&#xff1a; “您的连接不是私密连接”&#xff08;Chrome&#xff09;&#xff0c;如下图所示 “您的链接并不安全”&#xff08;Firefox&#xff09;&#xff0…

win10如何通过局域网从浏览器访问ip

1.打开控制面板&#xff0c;找到windows防火墙&#xff0c;找到高级设置&#xff0c;点击 点击公用配置文件下面的 Windows Defender 防火墙属性 3.修改预配置文件、专用配置文件、公用配置文件的入站连接&#xff0c;更改为运行 4.如下显示全是允许&#xff0c;就可以局域…