当前位置: 首页 > news >正文

红黑树浅浅学习

红黑树浅浅学习

    • 红黑树概念
    • 红黑树平衡性调整


红黑树概念

  • 二叉树:二叉树是每个节点最多有两个子树的树结构。
  • 二叉查找树:又称“二叉搜索树”,左孩子比父节点小,右孩子比父节点大,还有一个特性就是”中序遍历“可以让结点有序。
  • 平衡二叉树:它是一颗空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树。
  • 红黑树是一种自平衡的二叉查找树,它属于平衡树,但是却没有平衡二叉树那么“平衡”。可以保证在最坏情况下基本动态操作的时间复杂度为O(log n)。
  • 红黑树中的每个节点都有一个颜色属性,可以是红色或黑色。

红黑树满足以下5个性质:

  • 每个节点要么是红色的,要么是黑色的,根节点是黑色的。
  • 每个叶子节点(NIL节点,空节点)是黑色的。
  • 任何相邻节点不能同时为红色。
  • 任何叶子节点,到根节点,所经过的黑节点数目相同。
  • 当前节点到其所有叶节点包含的黑色节点数量相同。

通过这些性质,红黑树可以保证在插入和删除节点时,自动调整树的结构,以保持树的平衡和性质的满足。相比于普通的二叉查找树,红黑树的平衡性更好,查找、插入和删除都具有更稳定的时间复杂度,因此在很多场景下被广泛应用。
在这里插入图片描述


红黑树平衡性调整

  1. 依次插入 100 90 120,不需要进行平衡性调整
    在这里插入图片描述
  2. 插入85,把90和120变成黑色,100变成红色。但100必须为黑色,100也变成黑色
    在这里插入图片描述

平衡性调整情况1:爷节点为黑色,父节点为红色,且有叔节点为红色,父亲节点为爷节点的左孩子

  • 将父节点和叔节点都变为黑色。
  • 爷节点变成红色
    • 若爷节点变色之后红黑树性质出现问题,需要沿着爷节点继续向上调整
    • 若爷节点为根节点,要变黑色。
  1. 插入60为红色,红黑树继续进行调整,85变成黑色,90变成红色。
    在这里插入图片描述

平衡性调整情况2:爷节点为黑色,父节点为红色,没有叔节点或叔节点为黑色,父亲节点为爷节点的左孩子,插入的节点是父节点的左孩子

平衡性调整情况3:爷节点为黑色,父节点为红色,没有叔节点或叔节点为黑色,父亲节点为爷节点的右孩子,插入的节点是父节点的左孩子

平衡性调整情况4-6分别为1-3的反情况

#include <iostream>
#include <list>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <assert.h>
#include <sstream>
#include <stack>using namespace std;template<typename T>
struct RBNode{T data;RBNode* leftChild;RBNode* rightChild;RBNode* parentNd;bool isRed; //判断是否为红色节点。
};template<typename T>
class RBTree{
public:RBTree():root(nullptr){}~RBTree(){ReleaseNode(root);}void InsertElem(const T&e){InsertElem(root,e);}void InsertElem(RBNode<T>*& tNode, const T& e){ //第一个参数类型:指针引用RBNode<T>* point = tNode; // 从指向根节点开始RBNode<T>* parent = nullptr; // 保存父节点,根节点的父节点先为nullptr// 通过一个while循环寻找要插入节点的位置,同时还要把插入路线上所经过的所有节点都保存到栈中,因为这些节点的平衡因子可能要调整。while(point !=nullptr){if(e==point->data) return; //要插入的数据和当前树中某节点的数据相同,不允许插入parent = point; // 记录父节点if(e > point->data){point = point->rightChild;}else{point = point->leftChild;}}// end while// 走到这里,point 等于nullptr,该生成新节点了point = new RBNode<T>;point->data = e;point->leftChild = nullptr;point->rightChild = nullptr;point->parentNd = nullptr;point->isRed = true; //缺省插入的节点先给红色,之后才会判断需不需要进行调整if(parent == nullptr){// 创建的是根节点point->isRed = false;tNode = point;return;} // 创建的不是根节点,要把节点链接到父节点上if(e > parent->data){parent->rightChild = point;}else{parent->leftChild = point;}point->parentNd = parent;if(parent->isRed == false) return; //如果父节点是黑色,当前插入的又是红色节点,不需要做什么直接返回BalanceTune(point,parent);// 不管前面经历了什么,根节点固定黑色root->isRed = false;}private:// 获取兄弟节点指针RBNode<T>* getBrotherNode(RBNode<T>* p){// 由调用者确认p->parent 一定不为nullptrif(p->parentNd->leftChild == p){return p->parentNd->rightChild;}return p->parentNd->leftChild; }// 平衡性调整void BalanceTune(RBNode<T>* point, RBNode<T>* parent){// 能走到这里的,要插入的节点肯定至少在第三层了,因为如果是第二层,那么插入的节点都是红色的,父节点肯定是黑色的// 父节点为红色才能走下来(当前节点为红色,此时需要进行平衡性调整)RBNode<T>* parentBroNode = nullptr; //叔节点,可能不存在RBNode<T>* grandFatherNode = nullptr; //爷节点,因为父节点为红色,红色不能为根,那么至少都是爷节点做根while(true){parentBroNode = (parent->parentNd !=nullptr) ? (getBrotherNode(parent)):nullptr; //叔节点grandFatherNode = point->parentNd->parentNd; //爷节点// 不断向上调整,爷节点可能有为空的时候if(grandFatherNode == nullptr) break;// 如果叔节点为红色,那么爷节点不可能为红色if(parentBroNode != nullptr && parentBroNode->isRed == true){//平衡性调整情况1,没有将爷节点置为黑色的原因是统一在外部进行根节点为黑色的设置// 先处理变色问题// (1)父节点和叔节点变为黑色,爷节点变为红色parent->isRed = false;parentBroNode->isRed = false;grandFatherNode->isRed = true;// (2)如果爷节点是根,跳出循环,根节点颜色在循环外进行设置为黑色的处理if(grandFatherNode == root) break;// (3) 往上走继续循环point = grandFatherNode;parent = point->parentNd;if(parent->isRed = false) break;continue;} // 能走到这里的平衡性调整情况2,不满足if(parentBroNode != nullptr && parentBroNode->isRed == true)// 叔节点为黑色或叔节点为空的情况// 旋转变色之前的一些信息,这是通用代码RBNode<T>* gff = grandFatherNode->parentNd; //太爷节点int sign = 0; // 标记1:grandFatherNode是父节点的左孩子,标记2:grandFatherNode是父节点的右孩子。if(gff!=nullptr){if(gff->leftChild == grandFatherNode){sign = 1;}else{sign = 2;}}if(grandFatherNode->leftChild == parent){ //第一种情形,父亲是爷节点的左孩子// 开始旋转和变色以调整平衡if(parent->leftChild == point){ //新节点是父亲节点的左孩子// 右旋转RotateRight(grandFatherNode);}else{ //新节点是父亲节点的右孩子// 先左旋后右旋RotateLeftRight(grandFatherNode);}// 旋转之后变色的代码,通用grandFatherNode->isRed = false; //新的根节点设置为黑色grandFatherNode->rightChild->isRed = true; //新右叶子设置为红色}else{ // 第二种情形,父亲是爷节点的右孩子if(parent->rightChild == point){ //新节点是父亲的右孩子RotateLeft(grandFatherNode);}else{RotateRightLeft(grandFatherNode);}// 旋转变色之后的一些公用代码grandFatherNode->isRed = false; //新根设置为黑色grandFatherNode->leftChild->isRed = true; //新左叶子设置为红色}//*** 一些通用代码// 根已经改变了,所以要设置一些节点指向信息if(gff == nullptr){root = grandFatherNode;}else if(sign == 1){gff->leftChild = grandFatherNode;}else if(sign == 2){gff->rightChild = grandFatherNode;}break;}// end while(true)return;}// 右旋转void RotateRight(RBNode<T>*& pointer){ //注意参数类型RBNode<T>* ptmproot = pointer;pointer = ptmproot->leftChild;pointer->parentNd = ptmproot->parentNd;ptmproot->leftChild = pointer->rightChild;if(pointer->rightChild){pointer->rightChild->parentNd =ptmproot;}pointer->rightChild = ptmproot;ptmproot->parentNd = pointer;}void ReleaseNode(RBNode<T>* pnode){if(pnode !=nullptr){ReleaseNode(pnode->leftChild);ReleaseNode(pnode->rightChild);}delete pnode;}private:RBNode<T>* root; 
};int main()
{RBTree<int> myrbtr;int array[] = {80,50,120,30,60,20,40};int acount = sizeof(array)/sizeof(int);for(int i=0;i<acount;i++){myrbtr.InsertElem(array[i]);}return 0;
}

= =

相关文章:

红黑树浅浅学习

红黑树浅浅学习 红黑树概念红黑树平衡性调整 红黑树概念 二叉树&#xff1a;二叉树是每个节点最多有两个子树的树结构。二叉查找树&#xff1a;又称“二叉搜索树”&#xff0c;左孩子比父节点小&#xff0c;右孩子比父节点大&#xff0c;还有一个特性就是”中序遍历“可以让结…...

QGraphicsView 如何让图形大小适配窗口

1. setSceneRect 做什么用&#xff1f; setSceneRect是一个Qt中的函数&#xff0c;用于设置QGraphicsView中的场景矩形&#xff08;QRectF&#xff09;。 QGraphicsView是一个用于显示和编辑图形场景的控件&#xff0c;而setSceneRect函数用于设置场景矩形&#xff0c;即指定…...

sqlmap使用教程(3)-探测注入漏洞

1、探测GET参数 以下为探测DVWA靶场low级别的sql注入&#xff0c;以下提交方式为GET&#xff0c;问号&#xff08;?&#xff09;将分隔URL和传输的数据&#xff0c;而参数之间以&相连。--auth-credadmin:password --auth-typebasic &#xff08;DVWA靶场需要登录&#xf…...

期待已久!阿里云容器服务 ACK AI 助手正式上线

作者&#xff1a;行疾 大模型技术的蓬勃发展持续引领 AI 出圈潮流&#xff0c;各行各业都在尝试采用 AI 工具实现智能增效。 2023 年云栖大会上&#xff0c;阿里云容器服务团队正式发布 ACK AI 助手&#xff0c;带来大模型增强智能诊断&#xff0c;帮助企业和开发者降低 K8s …...

[BUG] Authentication Error

前言 给服务器安装了一个todesk&#xff0c;但是远程一直就是&#xff0c;点击用户&#xff0c;进入输入密码界面&#xff0c;还没等输入就自动返回了 解决 服务器是无桌面版本&#xff0c;或者桌面程序死掉了&#xff0c;重新安装就好 sudo apt install xorg sudo apt inst…...

23种设计模式概述

学习设计模式对我们有什么帮助&#xff1f; 1.提高代码质量和可维护性&#xff1a;设计模式是经过验证的解决方案&#xff0c;有助于解决常见的设计问题。使用设计模式可以减少代码冗余&#xff0c;增强代码的可读性和可维护性&#xff0c;并提高代码的可靠性。 2.提升开发效率…...

英文阅读-LinkedIn‘s Tips for Highly Effective Code Review

LinkedIn的CR技巧 LinkedIn团队CodeReview经验与方法&#xff0c;原文来自https://thenewstack.io/linkedin-code-review/ 总结 Do I Understand the “Why”? 在提交pr的同时需要描述本次修改的“动机”&#xff0c;有助于提高代码文档质量。 Am I Giving Positive Feedbac…...

性能优化-高通的Hexagon DSP和NPU

原文来自【 Qualcomm’s Hexagon DSP, and now, NPU 】 本文主要介绍Qualcomm Hexagon DSP和NPU&#xff0c;这些为处理简单大量运算而设计的硬件。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xf…...

第137期 Oracle的数据生命周期管理(20240123)

数据库管理137期 2024-01-23 第137期 Oracle的数据生命周期管理&#xff08;20240123&#xff09;1 ILM2 Heat Map3 ADO4 优点5 对比总结 第137期 Oracle的数据生命周期管理&#xff08;20240123&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&#xff09; Orac…...

电脑的GPU太强了,pytorch版本跟不上,将cuda驱动进行降级

我的情况&#xff1a; 我买的电脑的GPU版本为rtx4060&#xff0c;但是装上相应的驱动后&#xff0c;cuda的版本为12.3&#xff0c;而现在pytorch中cuda安装命令的最新版本为12.1&#xff0c;所以我将电脑的驱动进行降级为cuda版本为10.1的。 最后成功安装cuda10.1版本的驱动 …...

1 认识微服务

1.认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 1.0.学习目标 了解微服务架构的优缺点 1.1.单体架构 单体架构&#xff1a;将业务的所有…...

PHP+SOCKET 服务端多进程处理多客户端请求 demo

服务端 $socket socket_create(AF_INET,SOCK_STREAM,SOL_TCP); socket_bind($socket,0,95012) or die( server bind fail: . socket_strerror(socket_last_error())); socket_listen($socket,5);$child 0; //初始化子进程数 while(true){$client socket_accept($socket);$pi…...

Matplotlib笔记:安装Matplotlib+常用绘图

Matplotlib Python的2D绘图库 安装Matplotlib 打开Anaconda Prompt切换环境&#xff08;默认是base&#xff0c;无需切换&#xff09;输入命令行安装pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib3.5.2 绘图 导入import matplotlib.pyplot as plt …...

Confluence6+mysql5.7安装避坑详细记录

目录 一、前言 二、下载与安装 1、版本和安装环境 2、安装数据库 3、配置数据库 4、安装confluence 三、Pj confluence 1、选择语言和产品安装 2、Pj 3、上传mysql驱动 4、重启Confluence服务继续安装 四、Confluence重启卸载方法 重启方法 方法一 方法二 卸载…...

YTM32的HSM模块在信息安全场景中的应用

YTM32的HSM模块在信息安全场景中的应用 文章目录 YTM32的HSM模块在信息安全场景中的应用引言应用场景&#xff1a;一点点密码学基础硬件&#xff1a;YTM32的信息安全子系统HCU外设模块硬件特性基本的应用操作流程&#xff0c;以计算AES-ECB为例硬件上对处理多块数据上的一些设计…...

时间序列大模型:TimeGPT

论文&#xff1a;https://arxiv.org/pdf/2310.03589.pdf TimeGPT&#xff0c;这是第一个用于时间序列的基础模型&#xff0c;能够为训练期间未见过的多样化数据集生成准确的预测。 大规模时间序列模型通过利用当代深度学习进步的能力&#xff0c;使精确预测和减少不确定性成为…...

CloudPanel RCE漏洞复现(CVE-2023-35885)

0x01 产品简介 CloudPanel 是一个基于 Web 的控制面板或管理界面,旨在简化云托管环境的管理。它提供了一个集中式平台,用于管理云基础架构的各个方面,包括虚拟机 (VM)、存储、网络和应用程序。 0x02 漏洞概述 由于2.3.1 之前的 CloudPanel 具有不安全的文件管理器 cook…...

WPF多值转换器

背景&#xff1a;实现Slider拖动可以调整rgb 单转换器&#xff1a;WPF中数据绑定转换器Converter-CSDN博客 在View中&#xff1a; <StackPanel Orientation"Vertical"><Slider x:Name"slider_R" Minimum"0" Maximum"255" Wi…...

x-cmd pkg | perl - 具有强大的文本处理能力的通用脚本语言

目录 介绍首次用户技术特点竞品进一步阅读 介绍 Perl 是一种动态弱类型编程语言。Perl 内部集成了正则表达式的功能&#xff0c;以及巨大的第三方代码库 CPAN;在处理文本领域,是最有竞争力的一门编程语言之一 生态系统&#xff1a;综合 Perl 档案网络 (CPAN) 提供了超过 25,0…...

Jedis(一)与Redis的关系

一、Jedis介绍&#xff1a; 1、背景&#xff1a; Jedis是基于Java语言的Redis的客户端&#xff0c;Jedis Java Redis。Redis不仅可以使用命令来操作&#xff0c;现在基本上主流的语言都有API支持&#xff0c;比如Java、C#、C、PHP、Node.js、Go等。在官方网站里有一些Java的…...

城通网盘解析工具:3步获取高速直连下载地址的终极方案

城通网盘解析工具&#xff1a;3步获取高速直连下载地址的终极方案 【免费下载链接】ctfileGet 获取城通网盘一次性直连地址 项目地址: https://gitcode.com/gh_mirrors/ct/ctfileGet 你是否还在为城通网盘的蜗牛下载速度而烦恼&#xff1f;每次下载大文件都要经历漫长的…...

并行LLM推理技术:Hogwild! Inference原理与应用

1. 并行LLM推理的技术背景与挑战在传统Transformer架构中&#xff0c;语言模型的推理过程本质上是顺序执行的——每个新token的生成都严格依赖于之前所有token的注意力计算结果。这种串行特性导致两个显著瓶颈&#xff1a;首先&#xff0c;硬件计算资源利用率低下&#xff0c;特…...

Docker容器化Emacs:构建可移植、一致的开发环境解决方案

1. 项目概述&#xff1a;为什么要在Docker里运行Emacs&#xff1f;如果你是一个Emacs的重度用户&#xff0c;或者是一个开发者&#xff0c;你很可能遇到过这样的困境&#xff1a;你精心配置的Emacs环境&#xff0c;在换了一台新电脑、升级了操作系统&#xff0c;或者需要在多台…...

量子私有信息检索(QPIR)技术解析与应用前景

1. 量子私有信息检索技术概述量子私有信息检索&#xff08;Quantum Private Information Retrieval, QPIR&#xff09;是密码学领域的一项突破性技术&#xff0c;它允许用户从数据库中检索特定条目而不泄露被查询的是哪个条目。这项技术的核心价值在于解决了隐私保护与数据获取…...

DownKyi技术架构解析:构建高性能B站视频下载引擎的工程实践

DownKyi技术架构解析&#xff1a;构建高性能B站视频下载引擎的工程实践 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印等&…...

MySQL 视图使用场景与限制

视图是把查询封装成「虚拟表」的方式&#xff0c;用对了简化查询&#xff0c;用错了性能爆炸。这篇说说视图的用法和注意事项。 什么是视图&#xff1f; -- 视图&#xff1a;保存好的 SQL 查询&#xff0c;像表一样使用 CREATE VIEW view_name AS SELECT column1, column2 FROM…...

基于 Next.js 的无头电商架构实战:从 Vercel Commerce 看现代全栈开发

1. 项目概述&#xff1a;一个面向未来的全栈电商起点如果你最近在琢磨着用 Next.js 搞一个电商网站&#xff0c;或者想找一个现代、开箱即用的全栈电商模板来启动项目&#xff0c;那你大概率已经听说过vercel/commerce这个仓库了。它不是某个具体的电商平台&#xff0c;而是一个…...

基于MCP协议构建AI金融数据可视化服务器:从原理到实战部署

1. 项目概述&#xff1a;一个为AI智能体提供实时金融数据可视化的MCP服务器最近在折腾AI智能体&#xff08;Agent&#xff09;的生态&#xff0c;发现一个挺有意思的痛点&#xff1a;当你想让AI帮你分析股票、基金或者加密货币时&#xff0c;它往往只能给你干巴巴的数字和文字描…...

数据流编排与异步任务调度中间件kelivo部署与实战指南

1. 项目概述与核心价值最近在折腾一个挺有意思的项目&#xff0c;叫“Chevey339/kelivo”。乍一看这个标题&#xff0c;可能有点摸不着头脑&#xff0c;它不像那些直接告诉你“XX管理系统”或“XX工具库”的项目名那么直白。但恰恰是这种看似神秘的命名&#xff0c;背后往往隐藏…...

开源提示词管理工具:本地化部署与AI工作流效率提升实践

1. 项目概述&#xff1a;一个为AI工作流设计的提示词管理利器如果你和我一样&#xff0c;每天都在和ChatGPT、Claude、Midjourney这些AI模型打交道&#xff0c;那你一定有过这样的烦恼&#xff1a;昨天精心调试好的、能稳定输出高质量代码的提示词&#xff0c;今天想用的时候&a…...