C++进阶:红黑树介绍及模拟实现
上次介绍了AVL树:C++进阶:AVL树详解及模拟实现(图示讲解旋转过程)
今天就来紧接着来红黑树啦!!!
文章目录
1.红黑树介绍
红黑树是一种自平衡的二叉搜索树,它在每个节点上增加了一个表示颜色的存储位,可以是红色(Red)或黑色(Black)。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的从而保证了查找、插入和删除操作的时间复杂度为 O ( l o g N ) O(logN) O(logN)
约束规则
-
每个结点是红色或者黑色
-
根节点是黑色
-
如果一个节点是红色的,则它的两个孩子结点是黑色的(不能有连续的红节点)
-
对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点
-
叶子节点(NIL节点)是黑色的(此处的叶子结点指的是空结点)
2.项目文件规划
头文件RBTree.h:进行模拟的编写
源文件test.cpp:进行测试,检查代码逻辑是否满足期望
3.整体框架(节点和Tree)
enum Colour//使用枚举来定义,后面模拟哈希时也会用到类似的
{
RED,
BLACK
};
template<class K,class V>
struct RBTreeNode
{
RBTreeNode<K, V>* _left;//左节点
RBTreeNode<K, V>* _right;//右节点
RBTreeNode<K, V>* _parent;//父亲节点
Colour _col;//颜色,红和黑嘛
pair<K,V> _kv;//节点里存pair
RBTreeNode(const pair<K, V>& kv)//都直接在初始化列表里初始化了
:_left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _kv(kv)
, _col(RED)//这里新插入的节点一定要是红色,黑色的话会直接破坏规则
{}
};
template<class K, class V>
class RBTree
{
typedef RBTreeNode<K, V> Node;//名字太长了,叫Node也更好理解
public:
private:
Node* _root = nullptr;//给上缺省值
};
4.RBL树的新节点插入
基本步骤:
查找插入位置: 首先,我们需要找到新节点应该插入的位置。从根节点开始,按照二叉搜索树的性质,逐级向左或向右比较键值,直到找到一个合适的位置。
插入新节点: 找到插入位置后,我们创建一个新的节点,颜色为红,并将其插入到树中。如果树为空,则新节点成为树的根节点。否则,将新节点插入到合适的位置,使得树仍然保持二叉搜索树的性质。
插入后有需要变化时情况很多,下面具体分析
因为新节点的默认颜色是红色,因此:如果其双亲节点的颜色是黑色,没有违反红黑树任何性质,则不需要调整;但当新插入节点的双亲节点颜色为红色时,就违反了性质三不能有连在一起的红色节点,此时需要对红黑树分情况来讨论:
如果新插入节点的父亲节点是黑,那根本不会违反规则,如果要调整只有如下情况:
bool Insert(const pair<K,V> kv)
{
if (_root == nullptr)//如果为空,直接更换新节点
{
_root = new Node(kv);
_root->_col = BLACK;//注意默认是红,这里