红黑树的插入(NGINX源码)

下载并查看NGINX源码

访问NGINX下载页面,找到所需版本

https://nginx.org/en/download.html

使用wget下载源码包,替换版本号为所需版本

wget http://nginx.org/download/nginx-1.24.0.tar.gz

解压源码包

tar -xzvf nginx-1.24.0.tar.gz

 进入解压后的目录

cd nginx-1.24.0

红黑树定义

红黑树是每个节点都带有颜色属性的二叉查找树。它是一种自平衡的二叉查找树,能够在插入和删除数据时通过特定操作保持二叉查找树的平衡性,从而获得较高的查找性能。除了二叉查找树的强制要求外,任何一棵有效的红黑树还必须满足以下性质:

  1. 节点颜色:每个节点要么是红色,要么是黑色。
  2. 根节点:根节点必须是黑色。
  3. 叶节点:所有叶节点都是黑色。
  4. 红色节点的子节点:红色节点的子节点必须是黑色(即不能有两个连续的红色节点)。
  5. 每个节点的黑高:从任何节点到其所有后代叶节点的路径上,必须包含相同数量的黑色节点。

红黑树数据结构 

红黑树节点结构体

存储了节点间的对应关系和节点的真实数据。

typedef ngx_uint_t  ngx_rbtree_key_t; // 方便更换key的属性
typedef struct ngx_rbtree_node_s  ngx_rbtree_node_t;struct ngx_rbtree_node_s {ngx_rbtree_key_t       key;    // 节点的键值,类型为ngx_rbtree_key_tngx_rbtree_node_t     *left;ngx_rbtree_node_t     *right;ngx_rbtree_node_t     *parent;u_char                 color;u_char                 data;    // 节点的数据,类型为u_char,通常存储附加的信息或标记
};

红黑树结构体

维护整个红黑树的根节点及定义插入的节点时执行的函数指针。

typedef struct ngx_rbtree_s  ngx_rbtree_t; 
// 函数指针类型ngx_rbtree_insert_pt定义如何将一个节点插入到红黑树中,可以将不同的插入策略传递给红黑树的操作函数
typedef void (*ngx_rbtree_insert_pt) (ngx_rbtree_node_t *root,ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);struct ngx_rbtree_s {ngx_rbtree_node_t     *root;ngx_rbtree_node_t     *sentinel;ngx_rbtree_insert_pt   insert;
};

红黑树插入节点node

给节点染色

#define ngx_rbt_red(node)               ((node)->color = 1)
#define ngx_rbt_black(node)             ((node)->color = 0)
#define ngx_rbt_is_red(node)            ((node)->color)
#define ngx_rbt_is_black(node)          (!ngx_rbt_is_red(node))
#define ngx_rbt_copy_color(n1, n2)      (n1->color = n2->color)

以node为支点右旋

示意图

代码 
// 以node为支点右旋
static ngx_inline void ngx_rbtree_right_rotate(ngx_rbtree_node_t **root, ngx_rbtree_node_t *sentinel,ngx_rbtree_node_t *node) {// 1 标记node的左孩子ngx_rbtree_node_t  *temp;temp = node->left; // 2 改变node的左指针及其左孩子的父指针//   如果其左孩子是叶节点,不用将叶节点的父指针指向nodenode->left = temp->right;if (temp->right != sentinel) {temp->right->parent = node;}// 3 改变temp的父指针,及其可能存在的父节点的孩子指针temp->parent = node->parent;if (node == *root) {*root = temp;} else if (node == node->parent->right) {node->parent->right = temp;} else {node->parent->left = temp;}// 4 改变temp的右指针及其右孩子的父指针temp->right = node;node->parent = temp;
}

 以node为支点左旋

示意图

代码 
static ngx_inline void ngx_rbtree_left_rotate(ngx_rbtree_node_t **root, ngx_rbtree_node_t *sentinel,ngx_rbtree_node_t *node) {// 1 标记node的右孩子ngx_rbtree_node_t  *temp;temp = node->right;// 2 改变node的右指针及其右孩子的父指针//   如果其右孩子是叶节点,不用将叶节点的父指针指向nodenode->right = temp->left;if (temp->left != sentinel) {temp->left->parent = node;}// 3 改变temp的父指针,及其可能存在的父节点的孩子指针temp->parent = node->parent;if (node == *root) {*root = temp;} else if (node == node->parent->left) {node->parent->left = temp;} else {node->parent->right = temp;}// 4 改变temp的左指针及其左孩子的父指针temp->left = node;node->parent = temp;
}

插入操作

流程图

代码
void ngx_rbtree_insert(ngx_rbtree_t *tree, ngx_rbtree_node_t *node) {ngx_rbtree_node_t  **root, *temp, *sentinel;root = &tree->root;    // 获取树的根节点地址,以便进行旋转操作sentinel = tree->sentinel;// 如果树为空,直接将node节点作为根节点if (*root == sentinel) {node->parent = NULL;node->left = sentinel;node->right = sentinel;ngx_rbt_black(node);  // 将新节点颜色设为黑色*root = node;return;}// node不是根节点不为空,调用插入函数将节点插入到正确位置tree->insert(*root, node, sentinel);// 当新节点不是根节点且其父节点为红色时,需要进行平衡调整while (node != *root && ngx_rbt_is_red(node->parent)) {// 如果父节点是祖父节点的左子节点if (node->parent == node->parent->parent->left) {// 获取叔叔节点(父节点的兄弟节点)temp = node->parent->parent->right;// 如果叔叔节点是红色if (ngx_rbt_is_red(temp)) {// 将父节点和叔叔节点都设为黑色,将祖父节点设为红色// 然后将祖父节点作为当前节点,继续向上调整ngx_rbt_black(node->parent);ngx_rbt_black(temp);ngx_rbt_red(node->parent->parent);node = node->parent->parent;}// 如果叔叔节点是黑色else {// 如果新节点是父节点的右子节点if (node == node->parent->right) {// 对父节点进行左旋操作node = node->parent;ngx_rbtree_left_rotate(root, sentinel, node);}// 将父节点设为黑色,祖父节点设为红色ngx_rbt_black(node->parent);ngx_rbt_red(node->parent->parent);// 对祖父节点进行右旋操作ngx_rbtree_right_rotate(root, sentinel, node->parent->parent);}} // 如果父节点是祖父节点的右子节点else {// 获取叔叔节点(父节点的兄弟节点)temp = node->parent->parent->left;// 如果叔叔节点是红色if (ngx_rbt_is_red(temp)) {// 将父节点和叔叔节点都设为黑色,将祖父节点设为红色// 然后将祖父节点作为当前节点,继续向上调整ngx_rbt_black(node->parent);ngx_rbt_black(temp);ngx_rbt_red(node->parent->parent);node = node->parent->parent;} // 如果叔叔节点是黑色else {// 如果新节点是父节点的左子节点if (node == node->parent->left) {// 对父节点进行右旋操作node = node->parent;ngx_rbtree_right_rotate(root, sentinel, node);}// 将父节点设为黑色,祖父节点设为红色ngx_rbt_black(node->parent);ngx_rbt_red(node->parent->parent);// 对祖父节点进行左旋操作ngx_rbtree_left_rotate(root, sentinel, node->parent->parent);}}}// 确保根节点为黑色ngx_rbt_black(*root);
}
叔叔节点是红色

4种情况,只列出两种。注意,这里的黑色矩形不是叶子节点,而是树。

祖父节点到插入节点是LL型

祖父节点到插入节点是LR型

祖父节点到插入节点是RR型

祖父节点到插入节点是RL型

推荐一下

https://github.com/0voice

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

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

相关文章

用nginx-rtmp-win32-master及ffmpeg模拟rtmp视频流

效果 使用nginx-rtmp-win32-master搭建RTMP服务 双击exe就可以了。切记整个目录不能有中文 README.md ,启用后本地的RTM路径: rtmp://192.168.1.186/live/xxx ffmpeg将地本地视频推RMTP F:\rtsp\ffmpeg-7.0.2-essentials_build\bin>ffmpeg -re -i F:\rtsp\123.mp4 -c c…

苹果为什么不做折叠屏手机?

苹果为什么不做折叠屏手机?折叠屏手机在最近这些年里边,可以说是市场的一个主要在手机上的增长点。你像华W最近推出这个三折叠手机,引起了整个市场的轰动。 可是,为什么苹果到今天为止不为所动,还在那不停地在现在的这…

Leetcode Hot 100刷题记录 -Day14(矩阵置0)

矩阵置0 问题描述: 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]示例 2:…

华为OD机试 - 端口合并(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,…

Web后端服务平台解析漏洞与修复、文件包含漏洞详解

免责申明 本文仅是用于学习检测自己搭建的Web后端服务平台解析漏洞、文件包含漏洞的相关原理,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》‌及其所在国…

mysql怎样优化count(*) from 表名 where …… or ……这种慢sql

一 问题描述 线上发现一条类似这样的慢sql(查询时长8s): select id,name,(select count(*) from t14 where t14.idt15.id or t14.id2t15.id) as cnt from t15 ; t14的id和id2字段上都有索引,但是因为条件里有or,导致…

电路设计学习(一)

FUSB302BUCX 可编程 USB Type-C 控制器,带 PD(默认 SNK) FUSB302BUCX 是一款由 ON Semiconductor 生产的 USB Type-C 控制器,用于实现 USB Type-C 和 USB Power Delivery (PD) 协议。它主要负责 USB Type-C 端口的检测、CC 引脚…

GESP C++二级样题卷

一、单选题(每题 2 分,共 30 分) 1.目前主流的计算机储存数据最终都是转换成( )数据进行储存。 ​ A.二进制 ​ B.十进制 ​ C. 八进制 ​ D.十六进制 2.已知大写字…

结构开发笔记(八):solidworks软件(七):装配图中让摄像头绕轴旋转起来

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/142176639 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…

量化交易backtrader实践(二)_基础加强篇(3)_策略类实践进阶

通过前面几节的实践,我们已经对股票数据的获取,pandasData数据的格式处理,到bactrader的DATAS结构以及里面的data的数据结构,以及在init和next函数中如何读取和计算都有了比较清晰的认知。我们通过一个最简的回测系统,…

C# 结合 Javascript 测试获取天气信息

目录 测试效果 范例运行环境 关键代码 C#获取网页数据 前端代码 JavaScript 实现 总结 测试效果 获取一些简单的天气信息,可以丰富我们的应用系统,比如开发一个小桌面,小组件,增加一些实用性的系统功能,本文将…

neo4j安装为服务+配置环境变量

目录 neo4j安装为服务 windows services 参照JDK,将neo4j加入到环境变量 neo4j安装为服务 windows services 我的上一篇文章详细写明了如何安装启动neo4j《neo4j安装启动教程对应的jdk配置》,文末的启动neo4j是通过cmd命令行访问bin目录,这…

Git+Jenkins 基本使用(Basic Usage of Git+Jenkins)

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

Java企业面试题2

1.语言的分代: 第1代:机器语言 机器语言是最底层的计算机编程语言,它是由二进制数构成的一系列指令,直接与计算机硬件交互。每个二进制位模式代表一条特定的指令或数据地址。因为它是直接在硬件上执行的,所以运行效率…

诚邀见证2024九章云极DataCanvas算力包产品发布会!

算力,是驱动全球智能化升级的关键力量,也是智算经济腾飞的主要燃料。 在智算经济腾起之际,我们洞察未来:算力不仅是生产力还将作为社会性普惠AI资源。我们思考未来:算力产品和模式需要何种创新才能够加速算力普惠的进程?我们定义未来:用单位…

react学习笔记一:react介绍

将view规划成一个个的组件,是一个响应式的声明式的设计。 虚拟dom,减少dom操作。vue的虚拟dom是在react的基础上拓展来的。 单向数据流:是一种数据流动的模式。数据流的方向是有上到下的,在react中主要是从父组件流向子组件。 …

计算机毕业设计 基于SpringBoot框架的网上蛋糕销售系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

【微处理器系统原理与应用设计第十三讲】通用同/异步收发器USART轮询模式应用设计

USART提供两设备之间的串行双工通信,并支持中断和DMA工作。采用轮询、中断和DMA三种方式进行数据收发。 一、功能需求 实现远程串行通信数据的回传确认。微处理器系统构成的测控设备通过USART(串口)与用户设备(上位机&#xff0…

【Python篇】Python 函数综合指南——从基础到高阶

文章目录 Python 函数综合指南1. 函数介绍1.1 什么是函数?1.2 定义函数示例:1.3 调用函数1.4 函数参数1.4.1 必需参数1.4.2 默认参数1.4.3 关键字参数1.4.4 可变长度参数 2. Python 内置函数2.1 字符串处理函数示例: 2.2 数学函数示例&#x…

基于Spring Boot的能源管理系统+建筑能耗+建筑能耗监测系统+节能监测系统+能耗监测+建筑能耗监测

介绍 建筑节能监测系统是基于计算机网络、物联网、大数据和数据可视化等多种技术融合形成的一套节能监测系统。 系统实现了对建筑电、水、热,气等能源、资源消耗情况的实时监测和预警、动态分析和评估,为用户建立了科学、系统的节能分析方法&#xff0c…