红黑树(RHTree)的结构与操作#/

本文详细介绍了红黑树的概念,这是一种自平衡的二叉搜索树,通过颜色属性确保路径平衡。文章列举了红黑树的五个性质,并展示了插入和删除节点的关键代码实现,包括旋转操作和平衡调整策略,旨在帮助读者理解红黑树的内部工作机制。
摘要由CSDN通过智能技术生成

红黑树概念

红黑树,是一种二叉搜索树,与一般二叉搜索树不同的是在每个结点上增加一个存储位表示结点的颜色,可以是RedBlack。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩,因而是接近平衡的。

性质

 它不仅仅具有二叉搜索树的特性,还必须满足以下特点:

  1. 根结点必须是黑色
  2. 每个结点不是黑的就是红的
  3. 如果一个节点是红色的,则它的两个孩子结点是黑色的 
  4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点 
  5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点) 
  6. 新插入的结点必须以红色结点插入

操作

红黑树树的插入操作

typedef enum { BLACK = 0, RED = 1 }Color_Type;

template<class Type>
class RBTree;

template<class Type>
class RBNode
{
	friend class RBTree<Type>;
public:
	RBNode(const Type& d = Type())
		:data(d), leftChild(nullptr), rightChild(nullptr), parent(nullptr), color(RED)
	{}
	~RBNode()
	{}
private:
	Type    data;
	RBNode* leftChild;
	RBNode* rightChild;
	RBNode* parent;
	Color_Type color;
};

template<class Type>
class RBTree
{
public:
	RBTree() :Nil(_Buynode()), root(Nil)
	{
		Nil->parent = Nil->leftChild = Nil->rightChild = nullptr;
		Nil->color = BLACK;
	}
public:
	void Insert(const Type& v)
	{
		Insert(root, v);
	}
	void Remove(const Type& key)
	{
		Remove(root, key);
	}
protected:
	void Insert_Fixup(RBNode<Type>*& t, RBNode<Type>* x);
	void Insert(RBNode<Type>*& t, const Type& v);
protected:
	void RightRotate(RBNode<Type>*& t, RBNode<Type>* p);
	void LeftRotate(RBNode<Type>*& t, RBNode<Type>* p);
protected:
	RBNode<Type>* _Buynode(const Type& v = Type())
	{
		RBNode<Type>* s = new RBNode<Type>(v);
		s->leftChild = s->rightChild = Nil;
		return s;
	}
private:
	RBNode<Type>* Nil;
	RBNode<Type>* root;
};

template<class Type>
void RBTree<Type>::LeftRotate(RBNode<Type>*& t, RBNode<Type>* p)
{
	RBNode<Type>* s = p->rightChild;
	p->rightChild = s->leftChild;
	if (s->leftChild != Nil)
		s->leftChild->parent = p;
	s->parent = p->parent;
	if (p->parent == Nil)
		t = s;
	else if (p == p->parent->leftChild)
		p->parent->leftChild = s;
	else
		p->parent->rightChild = s;
	s->leftChild = p;
	p->parent = s;
}

template<class Type>
void RBTree<Type>::RightRotate(RBNode<Type>*& t, RBNode<Type>* p)
{
	RBNode<Type>* s = p->leftChild;
	p->leftChild = s->rightChild;
	if (s->rightChild != Nil)
		s->rightChild->parent = p;
	s->parent = p->parent;
	if (p->parent == Nil)
		t = s;
	else if (p == p->parent->leftChild)
		p->parent->leftChild = s;
	else
		p->parent->rightChild = s;
	s->rightChild = p;
	p->parent = s;
}
/

template<class Type>
void RBTree<Type>::Insert(RBNode<Type>*& t, const Type& v)
{
	//1 按照BST规则插入节点
	RBNode<Type>* x = t, * pr = Nil;
	while (x != Nil)
	{
		if (v == x->data)
			return;

		pr = x;

		if (v < x->data)
			x = x->leftChild;
		else
			x = x->rightChild;
	}
	x = _Buynode(v);
	if (pr == Nil) //说明插入的节点为第一个根节点
	{
		t = x;
		t->parent = Nil;
	}
	else if (v < pr->data)
		pr->leftChild = x;
	else
		pr->rightChild = x;
	x->parent = pr;

	//2 调整平衡
	Insert_Fixup(t, x);
}

template<class Type>
void RBTree<Type>::Insert_Fixup(RBNode<Type>*& t, RBNode<Type>* x)
{
	while (x->parent->color == RED)
	{
		//不平衡
		RBNode<Type>* s;
		if (x->parent == x->parent->parent->leftChild)
		{
			//左分支
			s = x->parent->parent->rightChild;
			//状况三
			if (s->color == RED)
			{
				x->parent->color = BLACK;
				x->parent->parent->color = RED;
				s->color = BLACK;
				x = x->parent->parent;
			}
			else
			{
				//状况二
				if (x == x->parent->rightChild)
				{
					x = x->parent;
					LeftRotate(t, x);
				}
				//状况一
				x->parent->color = BLACK;
				x->parent->parent->color = RED;
				RightRotate(t, x->parent->parent);
			}
		}
		else
		{
			//右分支
			s = x->parent->parent->leftChild;

			//状况三
			if (s->color == RED)
			{
				x->parent->color = BLACK;
				x->parent->parent->color = RED;
				s->color = BLACK;
				x = x->parent->parent;
			}
			else
			{
				//状况二
				if (x == x->parent->leftChild)
				{
					x = x->parent;
					RightRotate(t, x);
				}
				//状况一
				x->parent->color = BLACK;
				x->parent->parent->color = RED;
				LeftRotate(t, x->parent->parent);
			}
		}
	}
	t->color = BLACK;
}

红黑树删除

template<class Type>
void RBTree<Type>::Remove(RBNode<Type>*& t, const Type& key)
{
	//1 按照BST规则删除节点
	RBNode<Type>* p = t, * q;
	while (p != Nil && p->data != key)
	{
		if (key < p->data)
			p = p->leftChild;
		else
			p = p->rightChild;
	}
	if (p == Nil) //要删除的节点不存在
		return;

	if (p->leftChild != Nil && p->rightChild != Nil)
	{
		q = p->leftChild;
		while (q->rightChild != Nil)
			q = q->rightChild;

		p->data = q->data;
		p = q;
	}

	if (p->leftChild != Nil)
		q = p->leftChild;
	else
		q = p->rightChild; //要么p真实指向p的右树,要么p指向空

	q->parent = p->parent;
	if (q->parent == Nil)
		t = q;
	else if (p == p->parent->leftChild)
		p->parent->leftChild = q;
	else
		p->parent->rightChild = q;

	//2 调整平衡
	if (p->color == BLACK)
	{
		if (q != Nil)
			q->color = BLACK;//组合4
		else
			Remove_Fixup(t, q); //组合2
	}

	delete p;
}

template<class Type>
void RBTree<Type>::Remove_Fixup(RBNode<Type>*& t, RBNode<Type>* x)
{
	while (x != t && x->color == BLACK)
	{
		RBNode<Type>* w; // 兄弟节点
		if (x == x->parent->leftChild)
		{
			//左分支
			w = x->parent->rightChild;

			//情形四
			if (w->color == RED)
			{
				w->color = BLACK;
				x->parent->color = RED;
				LeftRotate(t, x->parent);
				w = x->parent->rightChild;
			}

			//情形三
			if (w->leftChild->color != RED && w->rightChild->color != RED)
			{
				w->color = RED;
				if (x->parent->color == RED)
				{
					x->parent->color = BLACK;
					x = t;
				}
				else
					x = x->parent;
			}
			else
			{
				//情形二
				if (w->leftChild != Nil)
				{
					w->color = RED;
					w->leftChild->color = BLACK;
					w = w->leftChild;
					RightRotate(t, w->parent);
				}
				//情形一
				w = x->parent->rightChild;
				w->color = x->parent->color;
				x->parent->color = BLACK;
				w->rightChild->color = BLACK;
				LeftRotate(t, x->parent);
				x = t;
			}
		}
		else
		{
			//右分支
			w = x->parent->leftChild;
			//情形4
			if (w->color == RED)
			{
				w->color = BLACK;
				w->parent->color = RED;
				RightRotate(t, x->parent);
				w = x->parent->leftChild;
			}
			//情形3
			if (w->leftChild->color != RED && w->rightChild->color != RED)
			{
				w->color = RED;
				if (x->parent->color == RED)
				{
					x->parent->color = BLACK;
					x = t;
				}
				else
				{
					x = x->parent;
				}
			}
			else
			{
				//情形2
				if (w->rightChild != Nil)
				{
					w->color = RED;
					w->rightChild->color = BLACK;
					w = w->rightChild;
					LeftRotate(t, w->parent);
				}
				//情形1
				w = x->parent->leftChild;
				w->color = x->parent->color;
				x->parent->color = BLACK;
				w->rightChild->color = BLACK;
				RightRotate(t, x->parent);
				x = t;
			}
		}
	}
	t->color = BLACK;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值