红黑树(4) : 如果我们一定要插入一个黑色新非根节点呢?

版权声明:, https://blog.csdn.net/u011760195/article/details/85305168

红黑树(4) : 如果我们一定要插入一个黑色新非根节点呢?

前言

你一定或许存在过疑虑,为什么每次插入的新节点都是默认红色呢?
我们的回答是:为了最大限度地不破坏红黑树性质,而插入黑色节点一定会违反性质(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_

猜你喜欢

转载自blog.csdn.net/u011760195/article/details/85305168