版权声明:, https://blog.csdn.net/u011760195/article/details/85305168
前言
你一定或许存在过疑虑,为什么每次插入的新节点都是默认红色呢?
我们的回答是:为了最大限度地不破坏红黑树性质,而插入黑色节点一定会违反性质(4)
那么如果一定要插入黑色节点我们该怎么处理呢?
下面我们给出处理过程。
但这之前,为了方便,我们记:
x:待插入节点
p:被插入的节点
g:p的父亲
s:x的兄弟
u:x的叔叔
情况1
p为黑,s为空
略去对称和相似情况
修复过程很简单,左旋 p ,染红 p ,局部子树恢复高度,红黑树性质在全局得以恢复。
情况2
p为黑,s为红
略去对称和相似情况
我们给出的修复办法是,染红p,染黑s,此时局部子树恢复高度,但 p可能出现双红缺陷,导致修复位置上移。
情况3
p为红,此时父系节点情况:
u不存在,或为红色
略去对称和相似情况
仅需进行一次局部3+4重构即可
对于上图情况,我们直接右旋g,局部子树得以恢复高度,但p处可能引发双红缺陷继而向上传播。
总结
考察上面三种情况,不难发现默认插入红色节点的优点。
三种情况中:
仅情况1不会传播双红缺陷到上层,但也需要经行一次旋转操作
而情况2,3,则会直接传播双红缺陷到上层。
当我们默认插入红色节点:
情况1,2什么都不用做
情况3跳过局部3+4重构步骤,直接进行双红缺陷修正即可。
通过对比可见默认插入红色节点的优势。
至此,红黑树所有要点均已讲完,下面给出完整的C++实现代码。
红黑树完整C++代码
// 红黑树实现
// 2018年12月27日21:40:05
// Ayww
#ifndef _RBTREE_
#define _RBTREE_
// 红黑树
template <class _Elem > class _Tree {
protected:
#ifdef _DEBUG
public:
#endif // _DEBUG
class _Tree_Node;
typedef void(*_op_call_back_value)(_Elem const &);
typedef typename _Tree<_Elem> _Myt;
typedef typename _Tree<_Elem>::_Tree_Node _Mytn;
typedef void(*_op_call_back)(_Mytn const *);
typedef _op_call_back _Mycb;
typedef _op_call_back_value _Mycbv;
_Mytn *_root;
size_t _size;
// 左旋节点
void _left_rotate_at(_Mytn *it) {
_Mytn *p = it->parent, *n = it->rc, *y = nullptr;
if (n) {
y = n->lc;
it->parent = n;
n->lc = it;
it->rc = y;
if (y) y->parent = it;
n->parent = p;
if (!p) {
this->_root = n;
}
else {
if (p->lc == it) p->lc = n;
else p->rc = n;
}
}
}
// 右旋节点
void _right_rotate_at(_Mytn *it) {
_Mytn *p = it->parent, *n = it->lc, *y = nullptr;
if (n) {
y = n->rc;
it->parent = n;
n->rc = it;
it->lc = y;
if (y) y->parent = it;
n->parent = p;
if (!p) {
this->_root = n;
}
else {
if (p->lc == it) p->lc = n;
else p->rc = n;
}
}
}
// 重定向
_Mytn* _remove_redirect(_Mytn* it) {
_Mytn *p, *l, *r, *m;
l = it->lc;
r = it->rc;
if (l && r) {
p = it->parent;
if (p && p->lc == it) {
m = l->max();
}
else {
m = r->min();
}
it->value = std::move(m->value);
// 重定向要删除的元素
it = m;
}
return it;
}
// 删除
_Mytn* _remove_at(_Mytn* it, _Mytn** _hot = nullptr ) {
// 重构,使用迭代方式
_Mytn *x = it,*p , *l , *r,*m = nullptr ;
while (x) {
// 重定向
p = x->parent;
l = x->lc;
r = x->rc;
m = nullptr;
// 左右子树均不空
if (l && r) {
it = _remove_redirect(it);
continue;
}
if (l) {
if (p) {
if (p->lc == x) {
p->lc = l;
}
else {
p->rc = l;
}
}
else {
this->_root = l;
}
l->parent = p;
m = x->lc;
x = nullptr;
}
else {
if (p) {
if (p->lc == x) {
p->lc = r;
}
else {
p->rc = r;
}
}
else {
this->_root = r;
}
if (r) {
r->parent = p;
m = x->rc;
}
m = x->parent;
x = nullptr;
}
}
delete it;
--this->_size;
if (_hot && m) {
*_hot = m->parent;
}
// 将删除后的孩子节点返回
return m;
}
// 交换
void _swap(_Myt const& r) {
auto size = this->_size;
auto root = this->_root;
this->_size = r->_size;
this->_root = r->_root;
r->_size = size;
r->_root = root;
}
// 插入
_Mytn* _insert(_Elem const &v) {
_Mytn *it, *hot;
it = this->_root->find(v, &hot);
if (it) return it;
if (hot) {
if (v > hot->value) {
it = hot->rc = new _Mytn(v, _Tree_Node::red, nullptr, nullptr, hot);
}
else {
it = hot->lc = new _Mytn(v, _Tree_Node::red, nullptr, nullptr, hot);
}
}
else {
it = new _Mytn(v, _Tree_Node::black, nullptr, nullptr, nullptr);
_root = it;
}
++_size;
return it;
}
// RedBlackTree - 解决双红缺陷
void _fix_after_insert(_Mytn *it) {
_Mytn *p,*g,*u;
while (it) {
p = it->parent;
if (!p) { // 没有父亲 当前为根节点则设为黑色
it->color = _Tree_Node::black;
this->_root = it;
return;
}
else {
if (p->color == _Tree_Node::red) { // 父亲是红色,一定有黑色的祖父节点
g = p->parent;
if (p == g->lc) { u = g->rc; } // 获取叔叔节点
else { u = g->lc; }
if (u && u->color == _Tree_Node::red) { // 叔叔为红
// RR - 2
// 染黑p和u 染红g _fix_double_red(g)
p->color = _Tree_Node::black;
u->color = _Tree_Node::black;
g->color = _Tree_Node::red;
//_fix_double_red(g); // 尾递归
// 改用非递归版本
it = g;
g = nullptr;
u = nullptr;
continue;
}
else { // 叔叔不存在或为黑
// RR -1
if (u == g->rc) { // 如果u是g的右儿子
// 如果是p的右儿子 左旋p
if (p->rc == it) {
this->_left_rotate_at(p);
// 更新p
p = p->parent;
}
// 右旋g
this->_right_rotate_at(g);
}
else { // u是g的左儿子
// 如果是p的左儿子 右旋p
if (p->lc == it) {
this->_right_rotate_at(p);
// 更新p
p = p->parent;
}
// 左旋g
this->_left_rotate_at(g);
}
// 染黑p 染红g
p->color = _Tree_Node::black;
g->color = _Tree_Node::red;
return;
}
}
else {
// RR - 0
// 父亲是黑色 无需修复
return;
}
}
}
}
// RedBlackTree - 解决双黑缺陷
void _fix_before_remove(_Mytn *it) {
_Mytn *p, *s, *t ,*r;
r = it->lc ? it->lc : it->rc;
if ( it->color == _Tree_Node::red || (r && r->color == _Tree_Node::red) ) {
if (r) r->color = _Tree_Node::black;
return;
}
while (it) {
p = it->parent;
if (!p) { // it 是根节点
return;
}
// p不为空
s = it == p->lc ? p->rc : p->lc; // s必定不为空
t = nullptr;
// s 为黑
if (s->color == _Tree_Node::black) {
t = (s->lc && s->lc->color == _Tree_Node::red) ? s->lc : ((s->rc && s->rc->color == _Tree_Node::red) ? s->rc : nullptr);
if (t) { // BB - 1 有红色侄子
if (s == p->lc) {
if (t == s->rc) {
this->_left_rotate_at(s);
std::swap(s, t);
}
this->_right_rotate_at(p);
}
else {
// 尝试判断 s 的右孩子是不是红节点
t = (s->rc && s->rc->color == _Tree_Node::red) ? s->rc : t;
if (t == s->lc) {
this->_right_rotate_at(s);
std::swap(s, t);
}
this->_left_rotate_at(p);
}
// 染黑 t s设为p的颜色 染黑 p
t->color = _Tree_Node::black;
s->color = p->color;
p->color = _Tree_Node::black;
return;
}
else {
// BB - 2R
// 染黑 g 染红 s
s->color = _Tree_Node::red;
if (p->color == _Tree_Node::red) {
p->color = _Tree_Node::black;
return;
}
// BB - 2B
it = p;
continue;
}
}
else {
// s 为红
// BB - 3
if (s == p->lc) {
this->_right_rotate_at(p);
}
else {
this->_left_rotate_at(p);
}
s->color = _Tree_Node::black;
p->color = _Tree_Node::red;
continue;
}
}
}
public:
class iterator;
typedef typename _Tree<_Elem>::iterator _Myit;
typedef void(*_Mycbit)(_Myit const&);
_Tree(void):_root(nullptr), _size(0u){}
~_Tree(void) { if(_size) this->clear(); }
_Tree(_Myt const&) = delete;
_Myt& operator=(_Myt const& r) {
this->clear();
this->swap(r);
return *this;
}
// 黑高
size_t black_height(void) {
_Mytn *it = this->_root;
size_t h = 0u;
if (!it) return 0u;
while (it) {
if (it->color == _Tree_Node::black) {
++h;
}
it = it->lc;
}
return h;
}
// 搜索一个元素并返回迭代器
_Myit search(_Elem const &v) {
return _Myit(this->_root->find(v));
}
// 插入
_Myit insert(_Elem const &v) {
_Mytn *it = this->_insert(v);
_fix_after_insert(it); // 试图修复插入后任何可能出现的缺陷
return _Myit(it);
}
// 移除元素
_Myit erase(_Elem v) {
_Mytn *it = this->_root->find(v);
if (!it) return _Myit(nullptr);
// 经过重定向的节点最多只有一颗非空子树
it = this->_remove_redirect(it);
this->_fix_before_remove(it); // 试图修复删除后任何可能出现的缺陷
this->_remove_at(it);
return this->upper_bound(v);
}
// 下限
_Myit lower_bound(_Elem v, _Mytn **hot = nullptr) {
_Mytn *it = this->_root;
_Mytn *_hot = nullptr;
while (it) {
_hot = it;
if (it->value >= v) {
it = it->lc;
}
else {
it = it->rc;
}
}
if (_hot->value >= v) {
it = _hot;
}
else {
it = _hot->right();
}
if (hot) *hot = _hot;
return _Myit(it);
}
// 上限
_Myit upper_bound(_Elem v, _Mytn **hot = nullptr) {
_Mytn *it = this->_root;
_Mytn *_hot = nullptr;
while (it) {
_hot = it;
if (it->value > v) {
it = it->lc;
}
else {
it = it->rc;
}
}
if (_hot->value > v) {
it = _hot;
}
else {
it = _hot->right();
}
if (hot) *hot = _hot;
return _Myit(it);
}
// 迭代器
_Myit begin(void) const {
return iterator(this->_root->min());
}
// 迭代器
static _Myit end(void) {
return iterator(nullptr);
}
// 根
_Myit root(void) const {
return iterator(this->_root);
}
// 大小
size_t size(void) {
return this->_size;
}
// 空
bool empty(void) {
return !this->_size;
}
// 清空树
void clear(void) {
this->_size = 0u;
this->_root->clear();
this->_root = nullptr;
}
friend class _Tree<_Elem>::_Tree_Node;
};
// 红黑树节点
template <class _Elem > class _Tree<_Elem>::_Tree_Node {
protected:
#ifdef _DEBUG
public:
#endif // _DEBUG
enum COLOR :int {
red = 0,
black = 1
}color; // 颜色
_Elem value; // 值
_Mytn *lc; // 左孩子
_Mytn *rc; // 右孩子
_Mytn *parent; // 父节点
static void _internal_postorder_delete(_Mytn* it) {
if (!it) return;
_internal_postorder_delete(it->lc);
_internal_postorder_delete(it->rc);
delete it;
}
public:
explicit _Tree_Node(_Elem v = _Elem(), COLOR c = red, _Mytn *l = nullptr, _Mytn *r = nullptr, _Mytn *p = nullptr):value(v),color(c),lc(l),rc(r),parent(p){}
~_Tree_Node(){}
// 查找
_Mytn *find(_Elem v, _Mytn **hot = nullptr) {
_Mytn *it = this;
_Mytn *_hot = nullptr;
while (it && it->value != v) {
_hot = it;
if (it->value > v) {
it = it->lc;
}
else {
it = it->rc;
}
}
if (hot) *hot = _hot;
return it;
}
// 直接后继节点
_Mytn *next(void) {
auto it = this->rc;
while (it) {
it = it->lc;
}
return it;
}
// 前驱节点
_Mytn *left(void) {
auto it = this;
if (lc) {
it = this->lc;
while (it->rc) {
it = it->rc;
}
}
else {
while (it->parent && it->parent->lc == it) {
it = it->parent;
}
it = it->parent;
}
return it;
}
// 后继节点
_Mytn *right(void) {
auto it = this;
if (rc) {
it = this->rc;
while (it->lc) {
it = it->lc;
}
}
else {
while (it->parent && it->parent->rc == it) {
it = it->parent;
}
it = it->parent;
}
return it;
}
// 查找子树最小值
_Mytn* min(void) {
_Mytn *x = this, *hot = this;
while (x) {
hot = x;
x = x->lc;
}
return hot;
}
// 查找子树最大值
_Mytn* max(void) {
_Mytn *x = this, *hot = this;
while (x) {
hot = x;
x = x->rc;
}
return hot;
}
// 删除所有子树
void clear(void) {
_Mytn *p = this->parent;
if (p) {
if (p->lc == this) p->lc = nullptr;
else p->rc = nullptr;
}
// postorder
_internal_postorder_delete(this);
}
friend class _Tree<_Elem>::iterator;
friend class _Tree<_Elem>;
};
// 红黑树迭代器
template <class _Elem> class _Tree<_Elem>::iterator {
protected:
_Mytn *_p;
public:
_Elem operator*(void) {
return this->_p->value;
}
bool is_valid(void) {
return this->_p;
}
_Elem value(void) {
return this->_p->value;
}
_Myit& operator=(_Myit &&r) {
this->_p == nullptr;
std::swap(_p, r._p);
return *this;
}
_Myit& operator=(_Myit const&r) {
this->_p = r._p;
return *this;
}
bool operator==(_Myit const &r) {
return this->_p==r._p ;
}
bool operator!=(_Myit const &r) {
return this->_p != r._p;
}
bool operator!(void) {
return !this->_p;
}
_Myit& operator++(void) {
this->_p = _p->right();
return *this;
}
_Myit& operator--(void) {
this->_p = _p->left();
return *this;
}
_Myit left_child(void) {
return _Myit(this->_p->lc);
}
_Myit right_child(void) {
return _Myit(this->_p->rc);
}
_Myit parent(void) {
return _Myit(this->_p->parent);
}
bool is_black(void) {
return this->_p->color == _Tree_Node::black;
}
bool is_red(void) {
return this->_p->color == _Tree_Node::red;
}
_Mytn* get(void) {
return this->_p;
}
explicit iterator(_Mytn *n = nullptr) :_p(n) {}
iterator(_Myit const& it) :_p(it._p) {}
iterator(_Myit && it) :_p(it._p) {
it._p = nullptr;
}
friend class _Tree<_Elem>;
};
// RedBlackTree
typedef _Tree<int> RedBlackTree;
#endif // _RBTREE_