红黑树详解

红黑树的概念与性质

 前置知识

在学习红黑树之前,最好有二叉查找树和AVL树的基础,因为红黑树本质就是一种特殊的二叉查找树,而红黑树的操作中需要用到AVL树中旋转的相关知识。至于二叉查找树和AVL树,可以参考如下两篇博客:

二叉查找树:二叉查找树-CSDN博客

AVL树:AVL树详解_avl tree-CS  DN博客


红黑树是一种特殊的二叉查找树,顾名思义,红黑树的一个特性就是每个节点都有一个颜色特征,或为红或为黑。红黑树可以通过一系列的限制规则保证最长路径小于最短路径的两边,也就是说,红黑树的每一条路径长度的范围为[N, 2N],其中N为最短路径长度。

与AVL树不同的是,红黑树并不是严格意义上的平衡二叉树,降低了插入和旋转的次数,所以在经常进行增删的结构中性能比AVL树更优。

红黑树是通过如下5条性质/规则来维护的:

  1. 每个结点不是红色就是黑色
  2. 根节点必须是黑色的
  3. 红色节点的孩子结点只能是黑色的,即路径上不能出现两个连续的红节点
  4. 从任一节点到其每个叶子的所有路径,要包含相同数目的黑色节点
  5. 所有的叶子结点都是黑结点

注意,由于翻译的问题,这里的叶子节点实际上指的其实是NIL节点(空节点)。所以,第5条并不算是一条规则,而是一个性质的说明。

那么为什么说这几条性质就保证了最长路径不会大于最短路径的二倍呢?首先,根节点一定是黑的就保证了每条路径的开始都是一个黑色节点。不能出现连续的红节点而且每条路径的黑色结点数量要保持一致,这种的话最短路径的情况就是整条路径都为黑色的情况,而最长路径的情况就是一黑后面紧跟着一红结点。所以我们很容易应证,最长路径不会超过最短路径的二倍。

红黑树的插入

红黑树本质上就是一种特殊的二叉查找树,所以大纲上我们依旧是按照二叉查找树的方式来插入。但是特别的,红黑树还维护了结点的颜色这一特性,所以我们还需要额外维护结点的颜色已经遵循上述的条规则/性质。

首先我们要思考,插入新结点时,是将其初始化为红色还是黑色。我们知道红黑树要控制每条路径的黑色结点相同,所以为了安全起见,一般是插入节点都默认初始化为红色节点。特别的,红黑树还要保证根节点为黑色,所以我们还需要对根节点的情况特殊处理。也就是说,除了根节点的情况外,新插入的结点都是统一初始化为红色,后续就根据具体情况具体调整了。

那么新插入结点默认为红结点,就必然会出现插入之后连续两个红色结点的情况,那么我们可以将插入之后出现连续红色结点的各种情况分为两大类来说:

首先我们规定,cur为当前新插入的节点,p为父节点,g为祖父节点,u为叔叔节点。

  • 情况1:cur为红,p为红,u存在且为红,g为黑

这里需要解释一下,cur为新插入节点,如果p是红的,那么根据红黑树的性质,g一定是黑的。这种叔叔节点存在且为红的情况比较好处理,只需要让父亲节点p和叔叔节点u的颜色置黑,g节点置黑即可。

首先,把p和u置黑是因为不能出现连续的红色节点。而把g置红是因为g并不一定就是根节点,所以为了不影响本条路径的黑色节点的数量,是需要将p置红的。那么如果g真的为根节点的话不就又与性质冲突了吗?所以我们需要特殊情况特殊处理,一般来说前面照常操作,最后之间暴力将根节点颜色设置为黑色是一种较为简便好理解的方式。

我们要知道,红黑树节点调整要在保证不改变路径上黑色节点数量的情况下进行调整,所以当叔叔节点存在且为红的时候,我们就可以通过将叔叔节点置黑,使得在保证路径上黑色节点数量不变的前提下,调整两个连续的红色节点。

  • 情况2:cur为红,p为红,g为黑,u不存在/u存在且为黑

那么当叔叔节点为黑色呢?这时我们就无法直接通过简单颜色来进行调整了,此时就需要用到AVL树中提到的4个旋转了。根据p和cur的位置,共有四种旋转的情况。不过由于双旋与单旋之后原来g位置的节点可能为cur也可能为p,所以我们这时就不能单纯的将cur置红或置黑。而是将旋转之后原g位置的节点置黑,将其两个子节点置红,叔叔节点一直是黑的或者空,所以不用对其处理。

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

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

相关文章

oracle安装的肘腋之疾小合集

#临时空间指定 export TMP/tmp export TMPDIR/tmp #图形化显示框不全 java问题,使用系统自带的jre ./runInstaller -jreLoc/usr/local/jdk1.7.0_80/ #ins30131 Failed to access the temporary location 给/tmp/CVU*加x权限 #linux桌面太小 xrandr -s 1440x900_60…

Matplotlib图形注释_Python数据分析与可视化

Matplotlib图形注释 添加注释文字、坐标变换 有的时候单单使用图形无法完整清晰的表达我们的信息,我们还需要进行文字进行注释,所以matplotlib提供了文字、箭头等注释可以突出图形中重点信息。 添加注释 为了使我们的可视化图形让人更加容易理解&#…

vue中父组件直接调用子组件方法

vue2 中&#xff0c;父组件如何调用子组件的方法 在Vue 2中&#xff0c;父组件可以通过使用ref属性来引用子组件的实例&#xff0c;然后通过该实例调用子组件的方法。 首先&#xff0c;在父组件的模板中&#xff0c;给子组件添加一个ref属性&#xff1a; <template>&l…

在工业生产环境下,服务器没有互联网,如何通过代理自己的电脑上互联网?

服务器主机是CentOS7操作系统.&#xff0c;服务器的局域网是10.0.6.x网段。我的笔记本的以太网口的局域网ip是也是10.0.6.x&#xff0c;由于这个10.0.6.x的整个局域网是没有拨号上网的所有无法访问互联网。 但是&#xff0c;如果笔记本脸上wifi&#xff0c;wifi的网段是192.168…

长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl1, …, numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0 。 示例 1&#xff1a; 输入&#x…

MySQL 有多个普通索引时会取哪一个索引?

我们都知道MySQL在查询时底层会进行索引的优化&#xff0c;假设有两个普通索引&#xff0c;且where 后面也根据这两个普通索引查询数据&#xff0c;那么执行查询语句时会使用到那个索引&#xff1f; 为了方便演示&#xff0c;新建users表&#xff0c;新建idx_name、idx_city这两…

前端vue导出PPT,使用pptxgen.js

前言 公司新需求需要导出ppt给业务用&#xff0c;查阅资料后发现也挺简单的&#xff0c;记录一下。 如有不懂的可以留言&#xff01;&#xff01;&#xff01; 1.安装包 npm install pptxgenjs --save2.引入包 在需要使用的文件中引入 import Pptxgenfrom "pptxgenjs&…

Oracle研学-介绍及安装

一 ORACLE数据库特点: 支持多用户&#xff0c;大事务量的事务处理数据安全性和完整性控制支持分布式数据处理可移植性(跨平台&#xff0c;linux转Windows) 二 ORACLE体系结构 数据库&#xff1a;oracle是一个全局数据库&#xff0c;一个数据库可以有多个实例&#xff0c;每个…

nodejs+vue+python+PHP+微信小程序-留学信息查询系统的设计与实现-安卓-计算机毕业设计

1、用户模块&#xff1a; 1&#xff09;登录&#xff1a;用户注册登录账号。 2&#xff09;留学查询模块&#xff1a;查询学校的入学申请条件、申请日期、政策变动等。 3&#xff09;院校排名&#xff1a;查询国外各院校的实力排名。 4&#xff09;测试功能&#xff1a;通过入学…

Spring Boot WebSocket 客户端

介绍 WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议&#xff0c;它可以提供实时的、双向的数据传输。Spring Boot 提供了对 WebSocket 的支持&#xff0c;我们可以使用 Spring Boot WebSocket 客户端来连接到 WebSocket 服务器&#xff0c;并进行实时通信。 本文将…

python-选择排序

选择排序是一种简单直观的排序算法&#xff0c;它的基本思想是每一轮选择未排序部分的最小元素&#xff0c;然后将其放到已排序部分的末尾。这个过程持续进行&#xff0c;直到整个数组排序完成。(重点&#xff1a;通过位置找元素) 以下是选择排序的详细步骤和 Python 实现&…

HarmonyOS应用开发实战—登录页面【ArkTS】

文章目录 本页面实战效果预览图一.HarmonyOS应用开发1.1HarmonyOS 详解1.2 ArkTS详解二.HarmonyOS应用开发实战—登录页面【ArkTS】2.1 ArkTS页面源码2.2 代码解析2.3 心得本页面实战效果预览图 一.HarmonyOS应用开发 1.1HarmonyOS 详解 HarmonyOS(鸿蒙操作系统)是华为公司…

小程序首页白屏优化,并举例说明

小程序首页白屏优化 小程序首页白屏优化是指在用户进入小程序首页时&#xff0c;能够尽快展示内容&#xff0c;避免出现长时间的白屏加载状态&#xff0c;提升用户体验。以下是一些常见的小程序首页白屏优化方法&#xff1a; 减少首屏请求&#xff1a;尽量减少首页需要请求的资…

js粒子效果(一)

效果: 代码: <!doctype html> <html> <head><meta charset"utf-8"><title>HTML5鼠标经过粒子散开动画特效</title><style>html, body {position: absolute;overflow: hidden;margin: 0;padding: 0;width: 100%;height: 1…

DELL MD3600F存储重置管理软件密码

注意&#xff1a;密码清除可能会导致业务秒断&#xff0c;建议非业务时间操作 针对一台控制器操作即可&#xff0c;另一控制器会同步操作 重置后密码为空&#xff01; 需求&#xff1a;重置存储管理软件密码 管理软件中分配物理磁盘时提示输入密码(类似是否了解风险确认操作的提…

华为OD机试 - 二叉树计算(Java JS Python C)

目录 题目描述 输入描述 输出描述 用例 题目解析 JS算法源码 Java算法源码

io.lettuce.core.RedisCommandExecutionException

io.lettuce.core.RedisCommandExecutionException: ERR invalid password ERR invalid password-CSDN博客 io.lettuce.core.RedisCommandExecutionException /** Copyright 2011-2022 the original author or authors.** Licensed under the Apache License, Version 2.0 (the…

Rust UI开发(一):使用iced构建UI时,如何在界面显示中文字符

注&#xff1a;此文适合于对rust有一些了解的朋友 iced是一个跨平台的GUI库&#xff0c;用于为rust语言程序构建UI界面。 iced的基本逻辑是&#xff1a; UI交互产生消息message&#xff0c;message传递给后台的update&#xff0c;在这个函数中编写逻辑&#xff0c;然后通过…

2023-11-24--oracle--实验--[Merge 语句]

oracle--实验---Merge语句 1.认知Merge 语句 • merge 语句是 sql 语句的一种。在 SQL server 、 Oracle 数据库中可用&#xff0c; MySQL 中不可用。 • merge 用来合并 update 和 insert 语句。目的&#xff1a;通过 merge 语句&#xff0c;根据一张表&#xff08; 原数据表…

IOS免签封装打包苹果APP的方法

IOS免签app封装打包苹果APP的方法如下&#xff1a; 准备一个未签名的IPA文件。获取一个企业证书或个人证书&#xff0c;用于签名IPA文件。将证书添加到Keychain Access中。安装iOS App Signer&#xff08;可以在网上找到相关下载链接&#xff09;。打开iOS App Signer&#xf…