C++红黑树

为什么会有红黑树呢,其实红黑树就是在AVL树上的优化,由于AVL树使一颗平衡树,为了保持平衡需要多次进行选择。而红黑树减少了旋转的次数,进行了优化,保证最长路径不超过最短路径的2倍。

 红黑树的性质

1. 每个结点不是红色就是黑色

2. 根节点是黑色的

3. 如果一个节点是红色的,则它的两个孩子结点是黑色的

4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点

5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)

开始考虑插入情况

先定义插入节点(cur)的父节点定义为p(parent),p的父节点定义为g (grandpa) ,g的另外一个孩子定义为u(uncle)。

将所有插入的树初始化为红。

几种情况

在这里,只讨论p在g的左边情况,p在g的右边同样的思路。

根据上面分析,只需要对u进行讨论

cur分为新插入的与向上调节赋值的两类

cur也可以在p的右边

什么是上调

当出现情况二和2图的时候,就要上调。

拿情况二举例,2图与之无异。

在调节的过程中,cur可能在p的左边,也可能在p的右边,p可能在g的左边,p也可能在g的右边,这些情况交替出现,需要我们用if调节去判断。

当出现情况一和1图,情况二和2图,通过旋转就可以维持红黑树的性质。下面会讲如何旋转

当我们向上调节,会出现这种情况(这里只讲p在g的左边的情况)

第一幅图的旋转

第二幅图旋转

对于左边的情况总结一下

边界的处理

调节的代码


		while (cur!=_node&&parent!=_node)
		{
			if (parent->_color == BLACK)
			{
				return true;
			}
			else    //  paretn->_color==RED
			{
				if (parent == parent->_parent->_left)   //  cur 和 parent位于 g左边的情况
				{
					RBTreeNode* uncle = parent->_parent->_right;
					if (uncle == nullptr && cur == parent->_left)   //  开始即结束  直接变形
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent->_parent);
						parent->_color = BLACK;
						Grandp->_color = RED;
						return true;
					}
					else if (uncle == nullptr && cur == parent->_right)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent);
						RotateR(Grandp);
						Grandp->_color = RED;
						cur->_color = BLACK;
						return true;
					}
					else if (uncle->_color == RED)    //向上调    //  cur  位于  parent的左边 右边都行
					{
						parent->_color = BLACK;
						uncle->_color = BLACK;
						if (parent->_parent != _node)
						{
							parent->_parent->_color = RED;
						}
						cur = parent->_parent;
						parent = cur->_parent;
					}
					else if (uncle->_color == BLACK&&cur==parent->_left)  //  开始旋转
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent->_parent);
						parent->_color = BLACK;
						Grandp->_color = RED;
						return true;
					}
					else if (uncle->_color == BLACK && cur == parent->_right)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent);
						RotateR(Grandp);
						Grandp->_color = RED;
						cur->_color = BLACK;
						return true;
					}
				}
				else    //  parent==paretn->_parent->_right
				{
					RBTreeNode* uncle = parent->_parent->_left;
					if (uncle == nullptr && cur == parent->_right)  
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent->_parent);
						Grandp->_color = RED;
						parent->_color = BLACK;
						return true;
					}
					else if (uncle == nullptr && cur == parent->_left)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent);
						RotateL(Grandp);
						cur->_color = BLACK;
						Grandp->_color = RED;
						return true;
					}
					else if (uncle->_color == RED)  
					{
						parent->_color = BLACK;
						uncle->_color = BLACK;
						if (parent->_parent != _node)
						{
							parent->_parent->_color = RED;
						}
						cur = parent->_parent;
						parent = cur->_parent;
					}
					else if (uncle->_color == BLACK && cur == parent->_left)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent->_parent);
						parent->_color = BLACK;
						Grandp->_color = RED;
						return true;
					}
					else if (uncle->_color == BLACK && cur == parent->_right)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent);
						RotateL(Grandp);
						Grandp->_color = RED;
						cur->_color = BLACK;
						return true;
					}

				}
			}

		}
	}

完整代码

enum Color
{
	RED,
	BLACK
};
template<class K, class V>
struct RBTreeNode
{
	RBTreeNode* _left;
	RBTreeNode* _right;
	RBTreeNode* _parent;
	K _key;
	V _value;
	Color _color;
	RBTreeNode(const K& key, const V& value)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _color(RED)
		, _key(key)
		, _value(value)
	{
	}
};


template<class K, class V>
class RBTree
{
	typedef RBTreeNode<K, V> RBTreeNode;
public:
	RBTree()
		:_node(nullptr)
	{
	}

	bool Insert(const pair<K, V>& KV)
	{
		if (_node == nullptr)
		{
			_node = new RBTreeNode(KV.first, KV.second);
			_node->_color = BLACK;
			return true;
		}
		const K& key = KV.first;
		const V& value = KV.second;

		RBTreeNode* cur = _node;
		RBTreeNode* parent = _node;
		while (cur)
		{
			if (key < cur->_key)
			{
				parent = cur;
				cur = cur->_left;
			}
			else if (key > cur->_key)
			{
				parent = cur;
				cur = cur->_right;
			}
			else
			{
				return false;
			}
		}

		if (key < parent->_key)
		{
			parent->_left = new RBTreeNode(key, value);
			parent->_left->_parent = parent;
			parent->_left->_color = RED;
			cur = parent->_left;
		}
		if (key > parent->_key)
		{
			parent->_right = new RBTreeNode(key, value);
			parent->_right->_parent = parent;
			parent->_right->_color = RED;
			cur = parent->_right;
		}

		while (cur!=_node&&parent!=_node)
		{
			if (parent->_color == BLACK)
			{
				return true;
			}
			else    //  paretn->_color==RED
			{
				if (parent == parent->_parent->_left)   //  cur 和 parent位于 g左边的情况
				{
					RBTreeNode* uncle = parent->_parent->_right;
					if (uncle == nullptr && cur == parent->_left)   //  开始即结束  直接变形
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent->_parent);
						parent->_color = BLACK;
						Grandp->_color = RED;
						return true;
					}
					else if (uncle == nullptr && cur == parent->_right)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent);
						RotateR(Grandp);
						Grandp->_color = RED;
						cur->_color = BLACK;
						return true;
					}
					else if (uncle->_color == RED)    //向上调    //  cur  位于  parent的左边 右边都行
					{
						parent->_color = BLACK;
						uncle->_color = BLACK;
						if (parent->_parent != _node)
						{
							parent->_parent->_color = RED;
						}
						cur = parent->_parent;
						parent = cur->_parent;
					}
					else if (uncle->_color == BLACK&&cur==parent->_left)  //  开始旋转
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent->_parent);
						parent->_color = BLACK;
						Grandp->_color = RED;
						return true;
					}
					else if (uncle->_color == BLACK && cur == parent->_right)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent);
						RotateR(Grandp);
						Grandp->_color = RED;
						cur->_color = BLACK;
						return true;
					}
				}
				else    //  parent==paretn->_parent->_right
				{
					RBTreeNode* uncle = parent->_parent->_left;
					if (uncle == nullptr && cur == parent->_right)  
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent->_parent);
						Grandp->_color = RED;
						parent->_color = BLACK;
						return true;
					}
					else if (uncle == nullptr && cur == parent->_left)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent);
						RotateL(Grandp);
						cur->_color = BLACK;
						Grandp->_color = RED;
						return true;
					}
					else if (uncle->_color == RED)  
					{
						parent->_color = BLACK;
						uncle->_color = BLACK;
						if (parent->_parent != _node)
						{
							parent->_parent->_color = RED;
						}
						cur = parent->_parent;
						parent = cur->_parent;
					}
					else if (uncle->_color == BLACK && cur == parent->_left)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent->_parent);
						parent->_color = BLACK;
						Grandp->_color = RED;
						return true;
					}
					else if (uncle->_color == BLACK && cur == parent->_right)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent);
						RotateL(Grandp);
						Grandp->_color = RED;
						cur->_color = BLACK;
						return true;
					}

				}
			}

		}
	}


	void RotateL(RBTreeNode* root)
	{
		if (root == nullptr)
		{
			return;
		}

		RBTreeNode* rootR = root->_right;
		root->_right = rootR->_left;
		if (rootR->_left)
		{
			rootR->_left->_parent = root;
		}


		rootR->_left = root;
		RBTreeNode* g = root->_parent;
		root->_parent = rootR;


		if (root == _node)
		{
			_node = rootR;
			rootR->_parent = nullptr;
		}
		else
		{
			rootR->_parent = g;
			if (root == g->_left)
			{
				g->_left = rootR;
			}
			else
			{
				g->_right = rootR;
			}
		}
	}

	void RotateR(RBTreeNode* root)
	{
		if (root == nullptr)
		{
			return;
		}

		RBTreeNode* rootL = root->_left;
		root->_left = rootL->_right;
		if (rootL->_right)
		{
			rootL->_right->_parent = root;
		}


		rootL->_right = root;
		RBTreeNode* g = root->_parent;
		root->_parent = rootL;


		if (root == _node)
		{
			_node = rootL;
			rootL->_parent = nullptr;
		}
		else
		{
			rootL->_parent = g;
			if (root == g->_left)
			{
				g->_left = rootL;
			}
			else
			{
				g->_right = rootL;
			}
		}
	}
	
	void _InOrder(RBTreeNode* root)
	{
		if (root == nullptr)
		{
			return;
		}

		_InOrder(root->_left);
		cout << root->_key << " " << root->_value << endl;
		_InOrder(root->_right);
	}

	void InOrder()
	{
		_InOrder(_node);
	}

private:
	RBTreeNode* _node;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值