红黑树详谈

2024-03-29 13:44
文章标签 红黑树 详谈

本文主要是介绍红黑树详谈,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • 1. 红黑树的概念:
      • 2.对比AVL树和红黑树
      • 3.红黑树的性质
        • 问题1
        • 路径
      • 4.红黑树结点的定义:
      • 5.红黑树的插入:
        • 步骤1
        • 步骤二:
      • 6.红黑树的验证
      • 7.红黑树的删除:
      • 8.红黑树的应用

1. 红黑树的概念:

红黑树是一种二叉搜索树,但每个结点上增加一个存储位表示结点颜色(red/back),通过下面的红黑树性质和红黑树确保没有一条路径会比其他路径长出两倍
在这里插入图片描述

2.对比AVL树和红黑树

在这里插入图片描述

3.红黑树的性质

1.每个结点只有红黑两种颜色;
2…红黑树的根是黑色;
3.不能出现连续的红色结点;
4.每条路金包含相同数量的黑色结点;
以上4条性质可以保证红黑树的最长路径的节点数不会超过最短路径的节点数的二倍;

问题1

这里如何用性质来保证最长路径的节点数不会超过最短路径的节点数的二倍
在这里插入图片描述

路径

这里的路径和我们一般认识的路径不同;
在这里插入图片描述

4.红黑树结点的定义:

使用类来定义结点:并使用枚举定义一个颜色变量来存储红黑;

在这里插入图片描述

5.红黑树的插入:

红黑树的插入分两步:
1.找到cur要插入的位置;
2.对插入的结点的支路的红黑树进行判断;是否需要调整,如需要进行调整;

步骤1

代码:
在这里插入图片描述

步骤二:

步骤二有多种情况:

情况一:新节点的颜色默认是红色;如果双亲结点是黑色——————不需要调整;
情况二:新节点cur是红色;双情接结点p的颜色是红色;祖父节点g是黑色;叔叔结点u存在并为红色;
在这里插入图片描述
解决方式:p,u改为黑色;g改为红色;然后把g当成cur,继续向上调整;

情况三 :(单旋转)新节点的颜色是红色,父节点的颜色是红色,叔叔结点存在为黑/叔叔结点不存在;

(1)叔叔不存在
在这里插入图片描述
(2)叔叔存在且为黑
在这里插入图片描述

解决方式:旋转+变色;
(1)
p为g的左孩子,cur为p的zuo孩子,则进行右单旋;
相反
p为g的右孩子,cur为p的右孩子,则进行左单旋;
(2)
p,g变色-p变黑,g变红;
情况四:(双旋)cur红,p为红,g为黑,u不存在/u存在且为黑;

在这里插入图片描述
解决方式:
先对parent进行单旋,将gpc形成单旋树;最后按第3种方法进行单旋转;

插入代码如下:

bool Insert(const pair<K, V>& kv){if (_root == nullptr){_root = new Node(kv);_root->_col = BLACK;return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_kv.first < kv.first){parent = cur;cur = cur->_right;}else if(cur->_kv.first>kv.first){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(kv);cur->_col = RED;if (parent->_kv.first < kv.first){parent->_right = cur;cur->_parent = parent;}else{parent->_left = cur;cur->_parent = parent;}while (parent && parent->_col == RED){Node* grandfather = parent->_parent;if (parent==grandfather->_left){//       g//   p       u//cNode* uncle = grandfather->_right;if (uncle && uncle->_col == RED){parent->_col = BLACK;uncle->_col = BLACK;grandfather->_col = RED;cur = grandfather;parent = cur->_parent;}else{if (cur == parent->_left){//单旋//       g//     p   u//  cRotateR(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{//双旋//        g//     p     u//        cRotateL(parent);RotateR(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}else{//    g//  u   p//        cNode* uncle = grandfather->_left;if (uncle&&uncle->_col==RED){grandfather->_col = RED;uncle->_col = parent->_col = BLACK;cur = grandfather;parent = cur->_parent;}else{if (cur == parent->_right){RotateL(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{RotateR(parent);RotateL(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}}//这里是为了解决情况一_root->_col = BLACK;return true;}//左单旋转void RotateL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;parent->_right = subRL;subR->_left = parent;Node* parentParent = parent->_parent;parent->_parent = subR;if (subRL){subRL->_parent = parent;}if (_root == parent){_root = subR;subR->_parent = nullptr;}else{if (parentParent->_left == parent){parentParent->_left = subR;}else{parentParent->_right = subR;}subR->_parent = parentParent;}}//右单旋void RotateR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR)subLR->_parent = parent;Node* parentParent = parent->_parent;subL->_right = parent;parent->_parent = subL;if (_root == parent){_root = subL;subL->_parent = nullptr;}else{if (parentParent->_left == parent){parentParent->_left = subL;}else{parentParent->_right = subL;}subL->_parent = parentParent;}}

6.红黑树的验证

红黑树的检测分为两步:

  1. 检测其是否满足二叉搜索树(中序遍历是否为有序序列)
  2. 检测其是否满足红黑树的性质

性质如下:
1…红黑树的根是黑色;
2.不能出现连续的红色结点;
3.每条路金包含相同数量的黑色结点

代码如下

bool check(Node* root, int blacknum, const int refVal){//使用递归来判断是否存在连续红节点;和每条支路的黑色结点数目相同if (root == nullptr)//到达尾结点{if (blacknum != refVal){cout << "存在黑结点数目不相等的路径" << endl;return false;}return true;}if (root->_col == RED && root->_parent->_col == RED){cout << "有连续的红色结点" << endl;return false;}if (root->_col == BLACK){++blacknum;}return check(root->_left, blacknum, refVal)&& check(root->_right, blacknum, refVal);}void InOrder(){_InOrder(_root);cout << endl;}void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_kv.first << " ";_InOrder(root->_right);}bool IsBalance(){if (_root == nullptr){return true;}if (_root->_col == RED){return false;}int refval = 0;//参考值Node* cur = _root;while (cur){if (cur->_col == BLACK){++refval;}cur = cur->_left;}//将一条支路作为参考的黑结点个数的参考值;int blacknum = 0;return check(_root, blacknum, refval);}

7.红黑树的删除:

红黑树的删除本节不做讲解,有兴趣的同学可参考:《算法导论》或者《STL源码剖析》
红黑树的删除阿里讲解

8.红黑树的应用

  1. C++ STL库 – map/set、mutil_map/mutil_set
  2. Java 库
  3. linux内核
  4. 其他一些库

这篇关于红黑树详谈的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/858745

相关文章

详谈redis跟数据库的数据同步问题

《详谈redis跟数据库的数据同步问题》文章讨论了在Redis和数据库数据一致性问题上的解决方案,主要比较了先更新Redis缓存再更新数据库和先更新数据库再更新Redis缓存两种方案,文章指出,删除R... 目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二

红黑树的旋转

红黑树的基本性质 红黑树与普通的二叉搜索树不同,它在每个节点上附加了一个额外的属性——颜色,该颜色可以是红色或黑色。通过引入这些颜色,红黑树能够维持以下 5 个基本性质,以确保树的平衡性: 每个节点是红色或黑色。根节点是黑色。所有叶子节点(NIL 节点)是黑色。如果一个节点是红色的,那么它的两个子节点都是黑色的(即,红色节点不能有红色子节点)。从任一节点到其每个叶子节点的所有路径上都包含相同数

C++笔记19•数据结构:红黑树(RBTree)•

红黑树 1.简介:         红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或 Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路 径会比其他路径长出俩倍,因而是接近平衡的。 当搜索二叉树退化为单支树时,搜索效率极低,为了使搜索效率高,建立平衡搜索二叉树就需要"平衡树"来解决。上一篇博客介绍了AVL树,这

数据结构(13)——平衡二叉树(红黑树)

欢迎来到博主的专栏——数据结构 博主ID:代码小号 文章目录 红黑树红黑树节点之间的关系红黑树的插入uncle节点为红色uncle节点是黑色或者没有uncle节点 红黑树 平衡二叉树最出名的除了AVL树之外就是红黑树(RBTree),所谓红黑树,即拥有以下特性的平衡二叉树 (1)每个节点要么是红色,要么是黑色 (2)根节点必须是黑色 (3)红色节点的子节点必须是黑色 (

hello树先生——红黑树

红黑树 一.什么是红黑树二.红黑树的实现1.创建树节点结构2.插入功能的实现 三.提供一些常见二叉树接口四.进行平衡测试 一.什么是红黑树 红黑树是一种自平衡的二叉搜索树,具有以下特性: 节点颜色:每个节点要么是红色,要么是黑色。根节点:根节点始终是黑色。红色节点:红色节点的子节点不能是红色(即没有两个连续的红色节点)。黑色节点:从任何节点到其每个叶子节点的路径上,必须包含

详谈HTTPS SSL/TLS协议原理

点击上方“朱小厮的博客”,选择“设为星标” 后台回复"书",获取 后台回复“k8s”,可领取k8s资料 协议安全和加密越来越引起人们的重视和关注,今天就跟大家分享一点协议加密方面的知识。要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识。 大致了解几个基本术语(HTTPS、SSL、TLS)的含义大致了解 HTTP 和 TCP 的关系(尤其是 “短连接”VS“长连接”)大致了解加密算法

数据结构-高层数据结构:映射/字典(Map)【有序字典:基于二分搜索树、基于平衡二叉树、基于红黑树、基于链表】【无序字典:基于哈希表】

Map.java package map;/*** 映射*/public interface Map<K,V> {/*** 添加元素** @param key* @param value* @return void*/void add(K key,V value);/*** 删除元素** @param key* @return V*/V remove(K key);/*** 查看是

<C++> 红黑树

目录 1. 红黑树的概念 2. 红黑树的性质 3. 红黑树节点的定义 4. 红黑树的插入操作 5. 红黑树的验证 6. 红黑树与AVL树的比较 7. 红黑树的删除         红黑树比AVL树更优一些,因为AVL要求太严格,左右高度差不超过1,而红黑树采用颜色来控制,只要求最长路径不超过最短路径的2倍,属于近似平衡 1. 红黑树的概念         红黑树,是一种二叉搜索

深入理解红黑树:在C++中实现插入、删除和查找操作

深入理解红黑树:在C++中实现插入、删除和查找操作 红黑树是一种自平衡二叉搜索树,广泛应用于各种算法和系统中。它通过颜色属性和旋转操作来保持树的平衡,从而保证插入、删除和查找操作的时间复杂度为O(log n)。本文将详细介绍如何在C++中实现一个红黑树,并提供插入、删除和查找操作的具体实现。 红黑树的基本性质 红黑树具有以下性质: 每个节点要么是红色,要么是黑色。根节点是黑色。每个叶子节点

c++ 红黑树(自平衡二叉搜索树)

目录  红黑树的概念 红黑树的由来 红黑树的性质 红黑树结点的定义 红黑树的插入 情况一:插入结点的叔叔存在,且叔叔的颜色是红色。 情况二:插入结点的叔叔存在且颜色是黑色 / 叔叔不存在, 情况A:p为g的左孩子,cur为p的左孩子 情况B:p为g的右孩子,cur为p的右孩子 情况C:p为g的左孩子,cur为p的右孩子 情况D:p为g的右孩子,cur为p的左孩子 红黑树