【二叉树进阶】红黑树(Red Black Tree) - 平衡二叉搜索树
文章目录
- 一、红黑树的概念
- 二、红黑树的性质
- 2.1 红黑树和AVL树效率对比
- 三、红黑树的结构(KV模型)
- 四、红黑树的插入
- 4.1 插入节点
- 4.2 平衡化操作(难点)
- 4.2.1 情况一
- 4.2.2 情况二
- 4.2.3 情况三
- 4.3 总结
- 五、红黑树的验证
- 六、红黑树的删除(了解)
- 七、红黑树的应用
一、红黑树的概念
红黑树,是一种平衡二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是 Red 或 Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出2倍,因而是接近平衡的。
AVL树和红黑树:
- AVL树:严格平衡(左右子树高度差不超过1),所以AVL树的查找、插入、删除效率高:O(logN),但插入和删除节点后,要维持树的平衡状态,做的旋转处理还是很多的。
- 红黑树:近似平衡(控制最长路径不超过最短路径的2倍),变了一种方式来控制树的平衡,相较于AVL树,没有那么严格。
红黑树更多是一种折中的选择,它舍弃平衡二叉树的严格平衡,换取节点插入时尽可能少的调整。
因为红黑树的旋转情况少于AVL树,使得红黑树整体性能略优于AVL树,不然map和set底层怎么会用红黑树呢,包括很多语言的库里面都用了红黑树。
如果发明AVL树的人是天才的话,那么发明红黑树的人就是天才中的天才,太妙了。
二、红黑树的性质
【核心 & 重要】
每个结点不是红色就是黑色
根节点是黑色的
如果一个节点是红色的,则它的两个孩子结点必须是黑色的(这就约束了红黑树里面没有连续的红色节点)
对于每个结点,从该结点到其所有可到达的叶结点的路径中,均包含相同数目的黑色结点
(即==每条路径都有相同数量的黑色节点==,注意:路径是走到 NIL 空节点)
每个 NIL 叶子结点都是黑色的(此处的叶子结点指的是空结点)
如图,这颗红黑树有11条路径,每条路径都有两个黑节点(不包括NIL)
【思考】
为什么满足以上性质后,就能保证 最长路径中节点个数不会超过最短路径中节点个数的2倍 了呢(不包括NIL)
当某条路径最短时,这条路径必然都是由黑色节点构成。当某条路径长度最长时,这条路径必然是由红色和黑色节点交替构成的(性质3限定了不能出现两个连续的红色节点)。
而性质4又限定了从任一节点到其每个叶子节点的所有路径必须包含相同数量的黑色节点,这么来说最长路径上的黑节点的数目和最短路径上的黑节点的数目相等。
最短路径:全是黑节点,最长路径:一黑一红,交替出现,所以最长路径刚好是最短路径的2倍。
2.1 红黑树和AVL树效率对比
对于一棵拥有 n 个内部结点(不包括NIL叶子结点)的红黑树,树的最大高度为 h = 2log2(n + 1)
当红黑树是一颗满二叉树时,高度最小 h = log2(n+1),当红黑树中最长路径刚好是最短路径2倍的时候,红黑树的高度最大 h = 2log2(n+1)
如果数据量是10亿:
查找效率 | 查找次数(约等于) |
---|---|
AVL树:log2n | 30 |
红黑树:2log2n | 60 |
【结论】:
- 虽然AVL树的查找效率优于红黑树,但对于现在的CPU,查找30次和60次是没有什么区别的,可以认为红黑树和AVL树的查找效率几乎是一样的,简化后为 O(log2n)。
- 红黑树整体性能略优于AVL树(因为红黑树旋转情况少于AVL树)。
- 红黑树的插入删除比AVL树更便于控制操作。
- 红黑树和AVL树都是高效的平衡二叉树,增删改查的时间复杂度都是O(log2n),红黑树不追求绝对平衡,其只需保证最长路径不超过最短路径的2倍,相对而言,降低了旋转的次数,所以在经常进行增删的结构中性能比AVL树更优,而且红黑树实现比较简单,所以实际运用中红黑树更多。
三、红黑树的结构(KV模型)
和AVL树类似。
1、定义红黑树的节点结构
// 定义红黑颜色
enum Colour // 枚举类型,枚举值默认从0开始,往后逐个加1(递增)
{BLACK,RED
};// 红黑树节点的定义(KV模型)
template<class K, class V>
struct RBTreeNode
{pair<K, V> _kv; // 键值对Colour _col; // 用来标记节点颜色RBTreeNode<K, V>* _left; // 三叉链结构RBTreeNode<K, V>* _right;RBTreeNode<K, V>* _parent;// 构造函数RBTreeNode(const pair<K, V>& kv): _kv(kv), _col(RED), _left(nullptr), _right(nullptr), _parent(nullptr){}
};
2、定义红黑树结构
// 红黑树的定义(KV模型)
template<class K, class V>
class RBTree
{typedef RBTreeNode<K, V> Node;private:Node* _root;public:RBTree() :_root(nullptr) {} // 构造函数bool Insert(const pair<K, V>& kv); // 插入节点void RotateLeft(Node* parent); // 左单旋void RotateRight(Node* parent); // 右单旋bool IsBalance(); // 检测红黑树是否平衡void InOrder(); // 中序遍历// ......
private:void _InOrder(Node* root); // 中序遍历子函数// ......
};
【思考】:在节点的定义中,为什么要将节点的默认颜色给成红色的?
- 如果插入黑色节点,一定会破坏性质4(每条路径的黑色节点数量相等);
- 如果插入红色节点,可能会破坏性质3(树中不能出现两个连续的红色节点);
- 所以默认给红色。
四、红黑树的插入
红黑树是在二叉搜索树的基础上加上其平衡限制条件,因此红黑树的插入可分为两步:
- 按照二叉搜索树的规则插入新节点
- 检测新节点插入后,红黑树的性质是否遭到破坏,然后进行平衡化操作
4.1 插入节点
思考:插入的新节点是红色好还是黑色好呢?
红色好,如果插入黑色,一定会破坏性质4(每条路径的黑色节点数量相等);如果插入红色,可能会破坏性质3(树中不能出现两个连续的红色节点)
插入一个红色新节点后,检测红黑树的性质是否遭到破坏,分为2种情况:
如果其父节点颜色是黑色,没有违反红黑树任何性质,则不需要调整;
如果其父节点颜色是红色,则违反了性质3(树中不能出现两个连续的红色节点),此时需要对红黑树进行平衡化操作,分为以下几种情况来讨论
【二叉树进阶】红黑树(Red Black Tree) - 平衡二叉搜索树相关推荐
- 真c++ 从二叉树到红黑树(3)之二叉搜索树BST
此文章为从二叉树到红黑树系列文章的第三节,主要介绍介绍二叉搜索树BST,为AVL和RedBlack打下基础 文章目录 一.前面文章链接~(点击右边波浪线可以返回目录) 二.二叉搜索树BST的定义~ ...
- 真c++ 从二叉树到红黑树(4)之二叉平衡搜索树AVL
此文章为从二叉树到红黑树系列文章的第四节,主要介绍介绍二叉平衡搜索树AVL,当你理解了AVL,红黑树你就理解了一半了! 文章目录 一.前面文章链接~(点击右边波浪线可以返回目录) 二.由BST引入 ...
- 红黑树算法原理(从二叉搜索树讲起)
原文:红黑树深入剖析及Java实现,本文修改了原文的一些小错误,如果想看红黑树的Java实现可以到原文去看. 红黑树是平衡二叉查找树的一种.为了深入理解红黑树,我们需要从二叉查找树开始讲起. BST ...
- 红黑树(Red Black Tree)超详细解析
红黑树详解 什么是红黑树? 红黑树,是一种二叉搜索树的特化,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black. 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确 ...
- 红黑树Red/Black Tree
红黑树Red/Black Tree 建立二进制搜索树,我们得到红/黑树,旨在解决BST可能变得不平衡的问题.(BST[二叉搜索树],是对于任意的node x,如果node y是node x的左边的节点 ...
- 数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树
在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉 ...
- 红黑树(Red–black tree)
一.红黑树的概念: 在计算机科学中,红黑树是一种自平衡二叉搜索树.每个节点存储一个表示"颜色"("红"或"黑")的额外位,用于确保树在插入和 ...
- 红黑树 平衡二叉搜索树_红黑树:自我平衡的二叉搜索树,并举例说明
红黑树 平衡二叉搜索树 什么是红黑树? (What is a Red-Black Tree?) Red-Black Tree is a type of self-balancing Binary Se ...
- 二叉搜索树、平衡二叉搜索树和红黑树
文章目录 一. 二叉搜索树(Binary Sort Tree) 二. 二叉平衡搜索树(AVL) 三. 红黑树 一. 二叉搜索树(Binary Sort Tree) 二叉搜索树,又称为二叉排序树(二叉查 ...
最新文章
- 新浪微博登录接口实例
- conda创建子环境并注册kernel
- elasticsearch(es)分布式全文检索引擎 简介
- 皮一皮:当群聊被封,大家是如何聊天的...
- Python 抖音用户粉丝(公开)--分析与实现
- nohup 与 linux 程序后台执行
- 阿里云飞天大数据产品价值解读——《一站式高质量搜索开放搜索》
- python-《Python发展前景》
- Selenium Chrome浏览器的启动以及proxy设置
- 2020-07-17
- Android5.1打开Emmagee显示错误
- 彩信 添加 html,彩信接口 | 微米-中国领先的短信彩信接口平台服务商
- [codeforces 1293A] ConneR and the A.R.C. Markland-N 不超时的二分/无限长数组map+桶排序
- win10如何截屏_win10使用技巧分享!
- 【折腾服务器 1】妖板 Intel N5105 + i226 主板安装 ESXi 7.0 教程
- java转大数据的学习路线
- 全栈工程师的百宝箱:图形工具篇
- MATLAB 设置小的tick
- Mysql5.1安装与配置(win7-x64)
- 长除法计算平方根的方法总结与代码实现(C++, Python)
热门文章
- Wince系统设置开机启动方式--注册表方式
- 普通一本计算机科学,值得报考的22所“普通一本”,优势专业很不错!
- 如何让ElementUI中的时间控件禁止选中过去时间
- [资源分享]一个类似LOL的UNITY分享
- Prefix-Tuning: Optimizing Continuous Prompts for Generation翻译
- Java遍历Map效率对比
- 高仿淘宝分页:jQuery分页插件kkpager-Array-专题视频课程
- R语言导入excel数据
- 接触角及接触角值的可重复性如何?
- 子墨对酒《三国杀》里论模式(一)工厂模式