数据结构红黑树

红黑树是一种自平衡的二叉搜索树,它通过确保任何从根到叶子的路径上不会有两个连续的红节点并且从根到叶子的所有路径上有相同数量的黑节点,从而近似平衡。这种平衡保证了在最坏情况下插入、删除、查找操作都能在O(log n)时间复杂度内完成。

下面,我将逐步介绍红黑树的关键操作,包括节点的定义、插入操作以及调整(修复)操作。由于完整的源码和解析非常冗长,我将简要概述每个部分,并给出关键代码片段。

红黑树节点的定义

在实现红黑树之前,我们首先定义树中的节点,包括节点的颜色、键值、左右子节点以及父节点的引用:

class RedBlackNode<T extends Comparable<T>> {enum Color { RED, BLACK }T key;Color color;RedBlackNode<T> left;RedBlackNode<T> right;RedBlackNode<T> parent;public RedBlackNode(T key, Color nodeColor, RedBlackNode<T> left, RedBlackNode<T> right) {this.key = key;this.color = nodeColor;this.left = left;this.right = right;this.parent = null; // 父节点在插入时确定}
}

红黑树的插入操作

插入操作首先按照二叉搜索树的性质插入节点,之后会根据红黑树的性质进行一系列的调整。

public void insert(T key) {RedBlackNode<T> node = new RedBlackNode<T>(key, RedBlackNode.Color.RED, null, null);// 正常的BST插入操作if (root == null) {root = node;} else {insertNode(root, node);}// 插入后的调整操作fixAfterInsertion(node);
}

插入后的调整操作

插入节点后可能会违反红黑树的性质,因此需要进行调整。下面是调整操作的伪代码概述:

while (新节点不是根节点且新节点的父节点是红色) {if (父节点是祖父节点的左子节点) {uncle = 祖父节点的右子节点if (uncle是红色) {// Case 1: 叔叔节点也是红色父节点设为黑色叔叔节点设为黑色祖父节点设为红色新节点 = 祖父节点} else {if (新节点是父节点的右子节点) {// Case 2: 新节点是其父节点的右子节点新节点 = 父节点左旋转(新节点)}// Case 3: 新节点是其父节点的左子节点父节点设为黑色祖父节点设为红色右旋转(祖父节点)}} else {// 对称地处理父节点是祖父节点右子节点的情况...}
}
根节点设为黑色

左旋转示例

左旋转是在插入节点导致树不平衡时重新平衡树的操作之一。以下是左旋转的概念性Java代码:

void leftRotate(RedBlackNode<T> x) {RedBlackNode<T> y = x.right;x.right = y.left;if (y.left != null) {y.left.parent = x;}y.parent = x.parent;if (x.parent == null) {root = y;} else if (x == x.parent.left) {x.parent.left = y;} else {x.parent.right = y;}y.left = x;x.parent = y;
}

右旋转示例

右旋转是左旋转的对称操作,用于重新平衡树。

void rightRotate(RedBlackNode<T> y) {RedBlackNode<T> x = y.left;y.left = x.right;if (x.right != null) {x.right.parent = y;}x.parent = y.parent;if (y.parent == null) {root = x;} else if (y == y.parent.right) {y.parent.right = x;} else {y.parent.left = x;}x.right = y;y.parent = x;
}

细节和注意事项

  1. 颜色翻转: 在某些情况下,你需要改变父节点和叔叔节点的颜色,并进行旋转。
  2. 插入时的颜色: 新插入的节点总是红色的。
  3. 根节点的颜色: 每次插入或删除后,根节点应保持为黑色。
  4. 旋转:旋转操作是用来重新平衡树结构的。左旋是将节点向左下方转移,而右旋是将其向右下方转移。

实现红黑树的完整代码需要大量的时间和精力。通常情况下,大多数编程语言的标准库中已经包含了红黑树的实现,比如Java中的TreeMapTreeSet。如果你要实现自己的红黑树,建议详细阅读相关书籍或文档,并在严格控制下一步步实现。

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

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

相关文章

【原创 附源码】Flutter集成Apple支付详细流程(附源码)

最近有时间&#xff0c;特意整理了一下之前使用过的Flutter平台的海外支付&#xff0c;附源码及demo可供参考 这篇文章只记录Apple支付的详细流程&#xff0c;其他相关Flutter文章链接如下&#xff1a; 【原创 附源码】Flutter集成谷歌支付详细流程(附源码) 【原创 附源码】F…

《Java 简易速速上手小册》第2章:面向对象的 Java(2024 最新版)

文章目录 2.1 类和对象 - 构建你的小宇宙2.1.1 基础知识2.1.2 重点案例&#xff1a;设计一个简单的图书类2.1.3 拓展案例 1&#xff1a;学生管理系统2.1.4 拓展案例 2&#xff1a;账户管理系统 2.2 继承与多态 - 让一切变得更有趣2.2.1 基础知识2.2.2 重点案例&#xff1a;动物…

【51单片机】蜂鸣器(江科大)

11.1蜂鸣器 1.蜂鸣器介绍 蜂鸣器是一种将电信号转换为声音信号的器件,常用来产生设备的按键音、报警音等提示信号 蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器 有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定 无源蜂鸣器:内部不带振荡源,需…

p16-18列表展示

Vue.prototype.$axios axios 这里的Vue.prototype 相当于全局变量设置了一个属性&#xff1f; this.&axios,可以在任何位置使用&#xff1f; Vue.prototype.$httpUrl‘http://localhost:8090’ 所以我们可以把url也设置为属性 loadGet(){this.$axios.get(this.$httpUrl/…

C语言strlen和sizeof的区别

strlen和sizeof没有联系 前者是库函数&#xff0c;统计长度的标志是是否有\0 后者是操作符。计算长度的标志是字节数量。

Linux_线程

线程与进程 多级页表 线程控制 线程互斥 线程同步 生产者消费者模型 常见概念 下面选取32位系统举例。 一.线程与进程 上图是曾经我们认为进程所占用的资源的集合。 1.1 线程概念 线程是一个执行分支&#xff0c;执行粒度比进程细&#xff0c;调度成本比进程低线程是cpu…

本地部署 Stable Cascade

本地部署 Stable Cascade 0. 引言1. 事前准备2. 本地部署 Stable Cascade3. 使用 Stable Cascade 生成图片4. Stable Cascade Github 地址 0. 引言 Stable Cascade 模型建立在 Wrstchen 架构之上&#xff0c;它与 Stable Diffusion 等其他模型的主要区别在于它的工作潜在空间要…

软考27-上午题-查找

一、基本概念 1-1、查找表&#xff1a; 同一类型的数据元素构成的集合。 对查找表常用的操作&#xff1a; 从查找表中查询某个特定的元素&#xff1b;检索某个特定的元素的各种属性。 通常只进行这两种操作的查找表&#xff1a;静态查找表 1-1-2、静态查找表&#xff1a; 顺…

Vite中如何.env.development、.env.production 环境变量配置

1、首先在项目根目录创建.env.development、.env.production两个文件 .env.development文件 # 页面标题 VITE_APP_TITLE 测试环境标题# 开发环境配置 VITE_APP_ENV development# 开发环境 VITE_APP_BASE_API /dev-api.env.production文件 # 页面标题 VITE_APP_TITLE 生产环…

B2科目二考试项目笔记

B2科目二考试项目笔记 1 桩考1.1 右起点倒库1.2 移库&#xff08;左→右&#xff09;1.3 驶向左起点1.4 左起点倒库1.5 驶向右起点 2 侧方停车考试阶段&#xff08;从路边开始&#xff09;&#xff1a; 3 直角转弯4 坡道定点停车和起步5 单边桥6 通过限速限宽门7 曲线行驶8 连续…

[OPEN SQL] 删除数据

DELETE语句用于删除数据库表中的数据 本次操作使用的数据库表为SCUSTOM&#xff0c;其字段内容如下所示 航班用户(SCUSTOM) 需要删除以下数据 1.删除单条数据 语法格式 DELETE <dbtab> FROM <wa>. DELETE <dbtab> FROM TABLE <itab>. DELETE FROM &…

Linux makefile 大型多文件的处理

最简单的例子是 main.cpp test.cpp test.h 首先将这三个写好 然后的话 test.cpp 上面输出 helloworld 首先我们在同一个目录下创建一个makefile 文件 然后用vim 编辑它 如下图&#xff08;使用的c&#xff09; mybin 是我们的可执行程序 gcc是编译的命令 gcc 前面必…

vs 开发者powershell安装git

在 VS 开发者 PowerShell 中安装 Git 的方法是: 1. 打开 VS 开发者 PowerShell 2. 运行以下命令安装 chocolatey(一个 Windows 包管理器): Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol [System.Net.ServicePoin…

人形机器人专题:准直驱执行器深度:人形机器人执行器技术的前沿

今天分享的是人形机器人系列深度研究报告&#xff1a;《人形机器人专题&#xff1a;准直驱执行器深度&#xff1a;人形机器人执行器技术的前沿》。 &#xff08;报告出品方&#xff1a;招商证券&#xff09; 报告共计&#xff1a;34页 准直驱执行器具备独特优势 刚性执行器…

ArcgisForJS基础

文章目录 0.引言1.第一个ArcgisForJS应用程序1.1.安装部署ArcgisForJS1.2.实现ArcgisForJS应用程序 2.开发与调试工具2.1.集成开发环境2.2.调试工具2.3.Firebug 0.引言 ArcGIS API for JavaScript是一款由Esri公司开发的用于创建WebGIS应用的JavaScript库。它允许开发者通过调…

UI文件原理

使用UI文件创建界面很轻松很便捷&#xff0c;他的原理就是每次我们保存UI文件的时候&#xff0c;QtCreator就自动帮我们将UI文件翻译成C的图形界面创建代码。可以通过以下步骤查看代码 到工程编译目录&#xff0c;一般就是工程同级目录下会生成另一个编译目录&#xff0c;会找到…

Stable Diffusion主流UI详细介绍

Stable Diffusion目前主流的操作界面有WebUI、ComfyUI以及Fooocus 这里webui和fooocus在人机交互上的逻辑是一样的&#xff0c;fooocus界面更加简洁。 comfyui是在人机交互上是采用流程节点的交互逻辑&#xff0c;和上面略有区别。 界面分别如下&#xff1a; WebUI界面如下 we…

Spring 用法学习总结(二)之基于注解注入属性

Spring学习 5 基于注解方式创建对象6 基于注解注入属性 5 基于注解方式创建对象 注解是代码的特殊标记&#xff0c;可以简化xml配置&#xff0c;格式&#xff1a;注解名称(属性名称属性值&#xff09;&#xff0c;可以作用在类、方法、属性上 以下注解都可以创建bean实例 Com…

LeetCode 每日一题 Day 62 - 75

1686. 石子游戏 VI Alice 和 Bob 轮流玩一个游戏&#xff0c;Alice 先手。 一堆石子里总共有 n 个石子&#xff0c;轮到某个玩家时&#xff0c;他可以 移出 一个石子并得到这个石子的价值。Alice 和 Bob 对石子价值有 不一样的的评判标准 。双方都知道对方的评判标准。 给你…

提前部署游戏业务防护,为何如此重要?

现在做网络游戏的企业都知道服务器的安全对于我们来说很重要&#xff01;互联网上面的DDoS攻击和CC攻击等等无处不在&#xff0c;而游戏服务器对服务器的防御能力和处理能力要求更高&#xff0c;普通的服务器则是比较注重各方面能力的均衡。 随着游戏行业的壮大&#xff0c;网络…