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

红黑树

红黑树是一个相对的平衡,减少了旋转的消耗

  1. 一个节点不是红的就是黑的
  2. 根节点是黑的
  3. 一个节点是红的,孩子是黑的(没有连续的红色节点)
  4. 对于每个节点,从该节点到后代节点的简单路径,都包含相同的黑色(黑色节点的数量相等)
  5. 每个叶子节点都是黑色的(null节点)

最长路径不超过最短路劲的2倍
最短路径:全黑
最长路径: 一黑一红
假设每条路径黑节点是N,
n<=random path<=2n
路径要数到空位置
左右两边没那么均衡:整体的高度
假设红黑树中一中路径黑色节点=x
高度2x>=h>=x
全黑 一黑一红
2x-1<=N<=22x-1:N为节点个数

X>=logx(N),x<=log(N)/2

添加节点

添加节点主要是添加红色节点
以父亲为祖父的左节点为例

  1. 叔叔存在且为红色

    把父亲和叔叔都改成黑色
    把祖父改成红色

  2. 叔叔不存在或为黑色
    1. 我为父亲的左节点,进行一个右单旋,并把父亲改成黑色,把祖父改成红色
    2. 我为父亲的右节点,进行一个左右双旋,把我改黑,祖父改红

父亲为祖父的右节点与之相反

#pragma once
#include <iostream>
using namespace std;enum Color
{RED,BLACK
};
template <class K, class V>struct RBTreeNode
{RBTreeNode *_left;RBTreeNode *_right;RBTreeNode *_parent;pair<K, V> _kv;Color _col; //控制颜色RBTreeNode(const pair<K, V> &kv): _kv(kv), _left(nullptr), _right(nullptr), _parent(nullptr), _col(RED)//一开始的颜色给红色{}
};template <class K, class V>
class RBTree
{typedef RBTreeNode<K, V> Node;private:Node *_root;private:void _InOrder(Node *root){if (root == nullptr)return;_InOrder(root->_left);cout << root->_kv.first << " ";_InOrder(root->_right);}void RotateR(Node *parent){//右单旋转Node *subL = parent->_left;           //子节点Node *subLR = subL->_right;           //子节点的右节点Node *parentparent = parent->_parent; //出问题节点的父节点parent->_left = subLR;subL->_right = parent;parent->_parent = subL;if (subLR)subLR->_parent = parent;//和父节点的父节点连接if (parent == _root){//要旋转的节点已经是根//更新根_root = subL;_root->_parent = nullptr; //更新顶部}else{//父节点上面还有节点if (parentparent->_left == parent){//是左节点subL->_parent = parentparent;parentparent->_left = subL;}else{subL->_parent = parentparent;parentparent->_right = subL;}}}void RotateL(Node *parent) //左单旋{Node *subR = parent->_right;Node *subRL = subR->_left;Node *parentparent = parent->_parent;parent->_parent = subR;subR->_left = parent;parent->_right = subRL;if (subRL)subRL->_parent = parent;if (parent == _root){_root = subR;_root->_parent = nullptr;}else{if (parentparent->_right == parent){parentparent->_right = subR;subR->_parent = parentparent;}else{parentparent->_left = subR;subR->_parent = parentparent;}}}public:RBTree(): _root(nullptr){}bool Insert(const pair<K, V> &kv){if (_root == nullptr){_root = new Node(kv);_root->_col = BLACK;return true;}//Node *cur = _root;Node *parent = nullptr; //还要找到父亲while (cur){if (cur->_kv.first > kv.first) //比它小,在左边{parent = cur;cur = cur->_left;}else if (cur->_kv.first < kv.first) //比他大,在右边{parent = cur;cur = cur->_right;}else{return false;}}//走到这里,就可以链接上cur = new Node(kv);cur->_col = RED; //新增节点颜色给红色cur->_parent = parent; //链接上父亲if (parent->_kv.first > kv.first){//比他小,在左边parent->_left = cur;}else{parent->_right = cur;}//插入之前一定是红黑树//这里就要控制平衡,通过颜色//插入黑节点(影响路径),还是红节点(只影响自己的,不影响其他区域)//往上调整//我为红,父亲如果为红,爷爷一定是黑色// 1.叔叔存在且为红while (parent && parent->_col == RED) //往上处理,父亲颜色为红色,就要处理,黑色就不要处理,为红,就不是根{Node *grandparent = parent->_parent;if (parent == grandparent->_left){Node *uncle = grandparent->_right; //叔叔就是在右边//叔叔存在且为红if (uncle && uncle->_col == RED){//叔叔存在,且为红//变色,继续向上处理parent->_col = BLACK;uncle->_col = BLACK;grandparent->_col = RED;cur = grandparent; //继续迭代往上操作parent = cur->_parent;}//叔叔不存在else //不存在,或存在且为黑{//不存在,进行旋转//旋转+变色if (cur == parent->_left){RotateR(grandparent); //进行右单旋转//变色parent->_col = BLACK;grandparent->_col = RED;}else{//双旋//左右双旋// p进行右单旋,g左单旋,g变红藕,cur变黑,RotateL(parent);RotateR(grandparent);cur->_col = BLACK;grandparent->_col = RED;}break;}}else //父亲是祖父的右边{Node *uncle = grandparent->_left; //叔叔就是在右边//叔叔存在且为红if (uncle && uncle->_col == RED){//叔叔存在,且为红//变色,继续向上处理parent->_col = BLACK;uncle->_col = BLACK;grandparent->_col = RED;cur = grandparent; //继续迭代往上操作parent = cur->_parent;}//叔叔不存在else //不存在,或存在且为黑{//不存在,进行旋转//旋转+变色if (cur == parent->_right){RotateL(grandparent); //进行右单旋转//变色parent->_col = BLACK;grandparent->_col = RED;}else{RotateR(parent);RotateL(grandparent);cur->_col = BLACK;grandparent->_col = RED;}break;}}}_root->_col = BLACK; //根的一定是黑色return true;}bool IsBalance(){if(_root&&_root->_col==RED){cout<<"根节点是黑色"<<endl;return false;}int basevalue=0;//基准值Node* left=_root;while(left){if(left->_col==BLACK){basevalue++;}left=left->_left;}//用最左路径黑色节点的数量,做基准值int blacknum=0;//每个节点的黑色个数return _IsBalance(_root,basevalue,blacknum);}void InOrder() //不能验证是不是AVL树{_InOrder(_root);}private:bool _IsBalance(Node* root,int basevalue,int blacknum){//根节点是黑的//红色,孩子是黑色,没有连续的红节点//每个路径含有相同的黑色if(root==nullptr){//一条路径走完了if(basevalue!=blacknum){//每条路劲都有blacknumcout<<"存在黑色节点数量不相等"<<endl;return false;}return true;}if(root->_col==RED&&root->_parent->_col==RED)//红节点{//检查它的父亲,一定有  cout<<"出现连续的红节点"<<endl;return false;}if(root->_col==BLACK){blacknum++;}return _IsBalance(root->_left,basevalue,blacknum)&&_IsBalance(root->_right,basevalue,blacknum);//没有用引用,下面的加加,不会影响下面}
};void test()
{RBTree<int, int> rbt;int a[]={16,3,7,11,9,26,18,14,15};// int a[] = {4,2,6,1,3,5,15,7,16,14};for (auto e : a){rbt.Insert(make_pair(e, e));}cout<<rbt.IsBalance()<<endl;rbt.InOrder();
}

相关文章:

红黑树

红黑树是一个相对的平衡&#xff0c;减少了旋转的消耗 一个节点不是红的就是黑的根节点是黑的一个节点是红的&#xff0c;孩子是黑的&#xff08;没有连续的红色节点&#xff09;对于每个节点&#xff0c;从该节点到后代节点的简单路径&#xff0c;都包含相同的黑色&#xff0…...

RIP路由协议的更新(电子科技大学TCP/IP第二次实验)

一&#xff0e;实验目的 1、掌握 RIP 协议在路由更新时的发送信息和发送方式 2、掌握 RIP 协议的路由更新算法 二&#xff0e;预备知识 1、静态路由选择和动态路由选择 2、内部网关协议和外部网关协议 3、距离向量路由选择 三&#xff0e;实验原理 RIP 协议&#xff08…...

基于JWT实现用户身份认证

常见场景 账号/密码登录、手机号验证码登录、微信扫码登录 解决方案 基于Session认证方案 什么是session认证方案 服务端生成httpsession认证(内存-sessionId)sessionId写到浏览器cookie浏览器请求的header中自动带sessionId到服务端服务端校验sessionId是否合法 优点 .…...

SaltStack 远程命令执行漏洞(CVE-2020-16846)

目录 (一)漏洞描述 (二)漏洞复现 1、在vulhub上启动docker 2、访问docker靶机 https /ip:8000...

SAP 详细解析成本收集器

成本收集器作为成本对象&#xff0c;主要应用于按期间进行成本核算的情况&#xff0c;在这种情况下会把产品创建为成本收集器&#xff0c;实际成本的收集和差异的结算全部按照成本收集器进行处理&#xff0c;财务的成本分析也针对成本收集器进行。 成本收集器是按期间核算&am…...

Vision Transformer学习了什么-WHAT DO VISION TRANSFORMERS LEARN? A VISUAL EXPLORATION

WHAT DO VISION TRANSFORMERS LEARN? A VISUAL EXPLORATION 文章地址 代码地址 摘要 视觉转换器( Vision Transformers&#xff0c;ViTs )正在迅速成为计算机视觉的事实上的架构&#xff0c;但我们对它们为什么工作和学习什么知之甚少。虽然现有研究对卷积神经网络的机制进…...

一种全新的图像滤波理论的实验(三)

一、前言 2023年02月22日&#xff0c;我发布了滤波后&#xff0c;为针对异常的白色和黑色像素进行处理的实验&#xff0c;本次发布基于上下文处理的方案的实验&#xff0c;目的是通过基于加权概率模型滤波后&#xff0c;在逆滤波时直接修复大量的白色和黑色的异常像素&#xf…...

CV——day79 读论文:基于小目标检测的扩展特征金字塔网络

Extended Feature Pyramid Network for Small Object DetectionI. INTRODUCTIONII. RELATED WORKA. 深层物体探测器B. 跨尺度特征C. 目标检测中的超分辨率III. OUR APPROACHA. 扩展特征金字塔网络B. 特征纹理传输C. 交叉分辨蒸馏IV. EXPERIMENTSA. Experimental Settings1&…...

智能家居项目(五)测试串口功能

目录 一、写一个单独测试串口的demo 二、直接运行上一篇智能家居的代码 一、写一个单独测试串口的demo 1、TTL串口与树莓派的连接方式 &#xff08;1&#xff09;TTL的RXD和TXD针脚连接到树莓的TXD和RXD上&#xff08;T–>R R–>T&#xff09;&#xff0c;交叉连&…...

2023年全国最新道路运输从业人员精选真题及答案7

百分百题库提供道路运输安全员考试试题、道路运输从业人员考试预测题、道路安全员考试真题、道路运输从业人员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 71.根据《中华人民共和国安全生产法》&#xff0c;生产经营单位…...

python的所有知识点(含讲解),不看就亏死了

目录 简介 特点 搭建开发环境 版本 hello world 注释 文件类型 变量 常量 数据类型 运算符和表达式 控制语句 数组相关 函数相关 字符串相关 文件处理 对象和类&#xff0c;注&#xff1a;不是那个对象&#xff01;&#xff01;&#xff01;&#xff01;&…...

【Servlet篇】Response对象详细解读

文章目录Response 继承体系Response 设置响应数据设置响应行数据设置响应头数据设置响应体数据Response 重定向Response 响应字符数据Response 响应字节数据Response 继承体系 前面说到&#xff0c;我们使用 Request 对象来获取请求数据&#xff0c;使用 Response 对象来设置响…...

SAP FICO期初开账存货导入尾差

一、问题 1.AFS物料网格级别库存导入先除再乘有尾差&#xff1a; 旧系统数据迁移自两个系统&#xff1a;一个管理数量账&#xff08;网格级别&#xff09;&#xff0c;一个管理金额账&#xff08;物料级别&#xff09; 2.MB52分工厂与MB5L分工厂统计差异&#xff1a; M…...

微信商城小程序怎么做_分享实体店做微信商城小程序制作步骤

各行各业都在用微商城小程序开店&#xff0c;不管是餐饮店还是便利店&#xff0c;还是五金店。都是可以利用微信小程序开一个线上店铺。实现线上跟线下店铺更加全面的结合。维护好自己的老客户。让您的客户给您拉新&#xff0c;带来新客户。小程序经过这几年的快速发展和不断升…...

【moment.js】时间格式化插件

Moment.js 用于在JavaScript中解析&#xff0c;验证&#xff0c;操作和显示日期和时间。是一款在项目中使用频率极高的时间格式化工具&#xff0c;Ant Design Vue 组件中就是使用它来处理时间的。 安装 npm install moment --save # npm yarn add moment # Ya…...

微信小程序开发【壹】

随手拍拍&#x1f481;‍♂️&#x1f4f7; 日期: 2023.02.24 地点: 杭州 介绍: 2023.02.24上午十点&#xff0c;路过学院的教学楼时&#x1f3e2;&#xff0c;突然看见了一团粉红色。走进一看是一排梅花&#x1f338;&#xff0c;赶在它们凋零前&#xff0c;将它们定格在我的相…...

2 k-近邻算法

0 问题引入 想一想&#xff1a;下面图片中有三种豆&#xff0c;其中三颗豆品种未知&#xff0c;如何判断他们类型&#xff1f; 1 KNN概述 1.1 KNN场景 电影可以按照题材分类&#xff0c;那么如何区分 动作片 和 爱情片 呢&#xff1f; 动作片&#xff1a;打斗次数更多爱情…...

深入探究文件I/O

目录Linux 系统如何管理文件静态文件与inode文件打开时的状态返回错误处理与errnostrerror 函数perror 函数exit、_exit、_Exit_exit()和_Exit()函数exit()函数空洞文件概念实验测试O_APPEND 和O_TRUNC 标志O_TRUNC 标志O_APPEND 标志多次打开同一个文件验证一些现象多次打开同…...

【LeetCode】剑指 Offer(9)

目录 题目&#xff1a;剑指 Offer 25. 合并两个排序的链表 - 力扣&#xff08;Leetcode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目&#xff1a;剑指 Offer 26. 树的子结构 - 力扣&#…...

python 遍历可迭代对象的方法

python 遍历可迭代对象的方法 可迭代(iterable) 迭代(遍历)就是按照某种顺序逐个访问对象中的每一项。 Python中有很多对象都是可以通过for语句来直接遍历的&#xff0c;例如list、string、dict等&#xff0c;这些对象都是可迭代的&#xff0c;被称为可迭代对象。 可以将可迭…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

五子棋测试用例

一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏&#xff0c;有着深厚的文化底蕴。通过将五子棋制作成网页游戏&#xff0c;可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家&#xff0c;都可以通过网页五子棋感受到东方棋类…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...

Mac flutter环境搭建

一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...