红黑树本质是一个二叉搜索树,每个节点要么是红色,要么是黑色,加上一些特性,变成平衡二叉搜索树。
红黑树的插入、删除、查找操作的时间复杂度是 O(logN)。
红黑树的高度在 [logN, logN+1]。
规则 1:每个节点不是红色,就是黑色;
规则 2:根节点必须是黑色;
规则 3:如果一个节点是红色,那么它的孩子必须是黑色;
规则 4:任何一个节点向下遍历到其叶子节点,所经过的黑色节点必须相等;
规则 5:空节点必须是黑色;
红黑树的数据结构
struct Rb_tree_node
{
bool color;
struct Rb_tree_node *parent;
struct Rb_tree_node *left;
struct Rb_tree_node *right;
}
STL中红黑树的定义
typedef bool _Rb_tree_Color_type;
const _Rb_tree_Color_type _S_rb_tree_red = false;
const _Rb_tree_Color_type _S_rb_tree_black = true;
struct _Rb_tree_node_base
{
typedef _Rb_tree_Color_type _Color_type;
typedef _Rb_tree_node_base* _Base_ptr;
_Color_type _M_color; // 颜色
_Base_ptr _M_parent; // 父亲节点
_Base_ptr _M_left; // 左孩子节点
_Base_ptr _M_right; // 右孩子节点
// 找值最小节点
static _Base_ptr _S_minimum(_Base_ptr __x)
{
while (__x->_M_left != 0) __x = __x->_M_left;
return __x;
}
// 找值最大节点
static _Base_ptr _S_maximum(_Base_ptr __x)
{
while (__x->_M_right != 0) __x = __x->_M_right;
return __x;
}
}
template <class _Value>
struct _Rb_tree_node : public _Rb_tree_node_base
{
typedef _Rb_tree_node<_Value>* _Link_type;
_Value _M_value_field; // 键值
};
基类迭代器
实现基本的寻找下一个元素,上一个元素的功能
// RB-tree 的迭代器-基类
struct _Rb_tree_base_iterator
{
typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
typedef bidirectional_iterator_tag iterator_category; // 双向迭代器
typedef ptrdiff_t difference_type;
_Base_ptr _M_node; // 它用来与容器之间产生一个连接关系
// 供 operator++() 调用,找下一个大的元素
void _M_increment()
{
if (_M_node->_M_right != 0) { // 如果有右子节点,就向右走
_M_node = _M_node->_M_right;
while (_M_node->_M_left != 0) // 然后一直往左子树走到底
_M_node = _M_node->_M_left;
}
else {
_Base_ptr __y = _M_node->_M_parent; // 没有右子节点,找其父节点
while (_M_node == __y->_M_right) { // 当该节点为其父节点的右子节点,就一直向上找父节点
_M_node = __y;
__y = __y->_M_parent;
}
if (_M_node->_M_right != __y)
_M_node = __y;
}
}
// 供 operator--() 调用,找下一个小的元素
void _M_decrement()
{ // 红色节点,父节点的父节点等于自己
if (_M_node->_M_color == _S_rb_tree_red &&
_M_node->_M_parent->_M_parent == _M_node)
_M_node = _M_node->_M_right;
else if (_M_node->_M_left != 0) { // 找出 node 的左子树最大值
_Base_ptr __y = _M_node->_M_left;
while (__y->_M_right != 0)
__y = __y->_M_right;
_M_node = __y;
}
else {
_Base_ptr __y = _M_node->_M_parent;
while (_M_node == __y->_M_left) {
_M_node = __y;
__y = __y->_M_parent;
}
_M_node = __y;
}
}
};
左旋
// 左旋转 《CLRS》p177
inline void
_Rb_tree_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
{
_Rb_tree_node_base* __y = __x->_M_right;
__x->_M_right = __y->_M_left;
if (__y->_M_left !=0)
__y->_M_left->_M_parent = __x;
__y->_M_parent = __x->_M_parent;
if (__x == __root)
__root = __y;
else if (__x == __x->_M_parent->_M_left)
__x->_M_parent->_M_left = __y;
else
__x->_M_parent->_M_right = __y;
__y->_M_left = __x;
__x->_M_parent = __y;
}
插入一个节点
插入一个节点之后,分为4种情况,需要分类讨论,来重新调整红黑树的高度和颜色,使其符合红黑树的定义
// RB-tree 平衡调整 《CLRS》p178
inline void
_Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root)
{
__x->_M_color = _S_rb_tree_red;
while (__x != __root && __x->_M_parent->_M_color == _S_rb_tree_red) {
if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) {
_Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right;
if (__y && __y->_M_color == _S_rb_tree_red) {
__x->_M_parent->_M_color = _S_rb_tree_black; // 黑色1
__y->_M_color = _S_rb_tree_black;
__x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
__x = __x->_M_parent->_M_parent;
}
else {
if (__x == __x->_M_parent->_M_right) {
__x = __x->_M_parent;
_Rb_tree_rotate_left(__x, __root);
}
__x->_M_parent->_M_color = _S_rb_tree_black;
__x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
_Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root);
}
}
else {
_Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left;
if (__y && __y->_M_color == _S_rb_tree_red) {
__x->_M_parent->_M_color = _S_rb_tree_black;
__y->_M_color = _S_rb_tree_black;
__x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
__x = __x->_M_parent->_M_parent;
}
else {
if (__x == __x->_M_parent->_M_left) {
__x = __x->_M_parent;
_Rb_tree_rotate_right(__x, __root);
}
__x->_M_parent->_M_color = _S_rb_tree_black;
__x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;
_Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root);
}
}
}
__root->_M_color = _S_rb_tree_black;
}
我自己写的总结:
参考视频:red black trees 红黑树 超棒讲解
红黑树的删除
这个有点复杂,下次总结
参考 博客:
https://www.cs.usfca.edu/~galles/visualization/RedBlack.html
https://github.com/steveLauwh/Algorithms/blob/master/Tree/RB-tree/README.md