目录
一、认识红黑树:
1、红黑树概念:
接下来看看红黑树的全貌:
2、红黑树的性质:
如下图所示:
最长路径:红黑相间的路径
最短路径:全是黑节点的路径
3、红黑树节点的定义:
enum COLOR
{
RED,
BLACK
};
template<class K, class V>
struct RBTreeNode
{
RBTreeNode<K, V>* _left;
RBTreeNode<K, V>* _right;
RBTreeNode<K, V>* _parent;
pair<K, V> _kv;
COLOR col;
RBTreeNode(const pair<K, V>& kv)
:_left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _kv(kv)
, col(RED)
{}
};
二、红黑树的插入:
1、插入注意事项:
2、插入理解:
情况一:当新插入节点的uncle存在,且是红节点
对应的抽象图:
情况二:当新插入节点的uncle不存在
当uncle存在且为黑:
在上述中判断是单旋或者双旋是通过指针的指向来判断的
bool Insert(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->_left;
}
else if (cur->_kv.first < kv.first)
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
//走到这就是找到了
cur = new Node(kv);
cur->col = RED;
//再连接到这个红黑树中
if (parent->_kv.first > cur->_kv.first)
{
parent->_left = cur;
}
else//parent->_kv.first < cur->_kv.first
{
parent->_right = cur;
}
cur->_parent = parent;
//已经连接完成后
while (parent && parent->col == RED)
{
//这里祖父必定存在,因为如果进循环后parent就是red,然而red不可能为根节点,所以parent的parent必定存在
Node* grandfather = parent->_parent;
if (parent == grandfather->_left)
{
Node* uncle = grandfather->_right;
if (uncle && uncle->col == RED)
{
//修改颜色
uncle->col = BLACK;
parent->col = BLACK;
grandfather->col = RED;
//修改cur
cur = grandfather;
//修改parent继续指向cur的parent
parent = cur->_parent;
}
else//uncle不存在或者uncle为黑色就需要旋转了
{
if (cur == parent->_left)
{
RotateR(grandfather);
parent->col = BLACK;
grandfather->col = RED;
}
else//cur == parent->_right
{
RotateL(parent);
RotateR(grandfather);
cur->col = BLACK;
grandfather->col = RED;
}
break;
}
}
else//parent == grandfather->_right
{
Node* uncle = grandfather->_left;
if (uncle && uncle->col == RED)
{
//修改颜色
uncle->col = BLACK;
parent->col = BLACK;
grandfather->col = RED;
//修改cur
cur = grandfather;
//修改parent继续指向cur的parent
parent = cur->_parent;
}
else//uncle不存在或者uncle为黑色就需要旋转了
{
if (cur == parent->_right)
{
RotateL(grandfather);
parent->col = BLACK;
grandfather->col = RED;
}
else//cur == parent->_right
{
RotateR(parent);
RotateL(grandfather);
cur->col = BLACK;
grandfather->col = RED;
}
break;
}
}
}
_root->col = BLACK;
return true;
}
//左单旋
void RotateL(Node* parent)
{
Node* cur = parent->_right;
Node* curleft = cur->_left;
parent->_right = curleft;
if (curleft)
{
curleft->_parent = parent;
}
cur->_left = parent;
//将parent的父节点保存起来
Node* pparent = parent->_parent;
parent->_parent = cur;
if (parent == _root)
{
_root = cur;
cur->_parent = nullptr;
}
else
{
if (pparent->_kv.first < cur->_kv.first)
{
pparent->_right = cur;
}
else //if (pparent->_kv.first > cur->_kv.first)
{
pparent->_left = cur;
}
cur->_parent = pparent;
}
}
//右单旋
void RotateR(Node* parent)
{
Node* cur = parent->_left;
Node* curright = cur->_right;
parent->_left = curright;
if (curright)
{
curright->_parent = parent;
}
cur->_right = parent;
//将parent的父节点保存起来
Node* pparent = parent->_parent;
parent->_parent = cur;
if (parent == _root)
{
_root = cur;
cur->_parent = nullptr;
}
else
{
if (pparent->_kv.first < cur->_kv.first)
{
pparent->_right = cur;
}
else //if (pparent->_kv.first > cur->_kv.first)
{
pparent->_left = cur;
}
cur->_parent = pparent;
}
}
三、红黑树的检查:
性质三检查:
性质四检查:
bool CheckColor(Node* root, int blacknum, int benchmark)
{
if (root == nullptr)
{
if (blacknum != benchmark)
{
cout << "黑色节点的数量不匹配" << endl;
return false;
}
return true;
}
if (root->col == BLACK)
{
++blacknum;
}
if (root->col == RED && root->_parent && root->_parent->col == RED)
{
cout << root->_kv.first << "出现连续红色节点" << endl;
return false;
}
return CheckColor(root->_left, blacknum, benchmark)
&& CheckColor(root->_right, blacknum, benchmark);
}
bool IsRBTree()
{
return _IsRBTree(_root);
}
bool _IsRBTree(Node* root)
{
if (root == nullptr)
return true;
if (root->col == RED)
{
return false;
}
//基准值
int benchmark = 0;
Node* cur = _root;
while (cur)
{
if (cur->col == BLACK)
++benchmark;
cur = cur->_left;
}
return CheckColor(root, 0, benchmark);
}