红黑树

红黑树(Red Black Tree) 是一种自平衡二叉查找树,典型的用途是实现关联数组

它是在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symmetric binary B-trees)。后来,在1978年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的“红黑树”。

红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。

它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。

红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:

性质1. 节点是红色或黑色。

性质2. 根节点是黑色。

性质3 每个叶节点(NIL节点,空节点)是黑色的。

性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

这些约束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这个树大致上是平衡的。因为操作比如插入、删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树。

要知道为什么这些特性确保了这个结果,注意到性质4导致了路径不能有两个毗连的红色节点就足够了。最短的可能路径都是黑色节点,最长的可能路径有交替的红色和黑色节点。因为根据性质5所有最长的路径都有相同数目的黑色节点,这就表明了没有路径能多于任何其他路径的两倍长。

在很多树数据结构的表示中,一个节点有可能只有一个子节点,而叶子节点不包含数据。用这种范例表示红黑树是可能的,但是这会改变一些属性并使算法复杂。为此,本文中我们使用 "nil 叶子" 或"空(null)叶子"(即哨兵节点),如上图所示,它不包含数据而只充当树在此结束的指示。这些节点在绘图中经常被省略,导致了这些树好象同上述原则相矛盾,而实际上不是这样。与此有关的结论是所有节点都有两个子节点,尽管其中的一个或两个可能是空叶子。

#include<iostream>
using namespace std;
typedef struct 
{
	Node* left;
	Node *right;
	Node *p;
	int key;
	char color;
} Node;
class RBTree
{
private:
	Node * T;
	Node *nil;
public:
	Node * Tree_MIN(Node *x)
	{
		while (x->left != NULL)
		{
			x = x->left;
		}
		return x;
	}
	Node * Tree_MAX(Node *x)
	{
		while (x->right != NULL)
		{
			x = x->right;
		}
		return x;
	}
	void INORED_TREE_WALK(Node* x)
	{
		INORED_TREE_WALK(x->left);
		cout << x->key << "  ";
		INORED_TREE_WALK(x->right);
	}
	Node* Tree_Search(Node* x, int k)
	{
		while (x != NULL && k != x->key)
		{
			if (k < x->key)
				x = x->left;
			else
				x = x->right;
		}
		return x;
	}
	Node * Tree_SUCCESSOR(Node *x)
	{
		if (x->right != NULL)
			return Tree_SUCCESSOR(x->right);
		Node *y = x->p;
		while (y != NULL && y->right == x)
		{
			x = x->p;
			y = x->p;
		}
		return y;
	}
	void Left_Rotate(Node *& T,Node *&x)
	{
		Node * y = x->right;
		x->right = y->left;
		if(y->left!=nil)//如果右孩子的左孩子不为哨兵节点的情况
			y->left->p = x;
		x->p = y;
		y->left = x;
		y->p = x->p;
		if (x->p == nil)//x为根节点的情况
			T = y;
		else if (x == x->p->left)
		{
			x->p->left = y;
		}
		else
		{
			x->p->left = y;
		}
	}
	void Right_Rotate(Node *& T, Node *&x)
	{
		Node *y = x->left;
		if(y->right!=nil)//如果左孩子的右孩子不为哨兵节点的情况
			y->right->p = x;
		x->left = y->right;
		x->p = y;
		y->right = x;
		if (x->p == nil)
			T = y;
		else if (x == x->p->left)
			y = x->p->left;
		else
			y = x->p->right;
	}
	void RE_Insert(Node * &T, Node *&x)
	{
		Node *m = T;
		Node *n = nil;
		while (m != nil)
		{
			n = m;
			if (x->key > n->key)
				m = n->right;
			else
				m = n->left;
		}
		x->p = n;
		if (n == nil)
			T = x;
		else if (x->key > n->key)
			x = n->right;
		else
			x = n->left;
		x->color = 'R';
		x->left = nil;
		x->right = nil;
		RB_Insert_Fixup(T, x);
	}
	void RB_Insert_Fixup(Node *&T, Node *&x)
	{
		while (x->p->color = 'R')
		{
			if (x->p == x->p->p->left)
			{
				Node *y = x->p->p->right;
				if (y->color == 'R')
				{
					x->p->color = 'B';
					x->p->p->left->color = 'B';
					x->p->p->color = 'R';
					x = x->p->p;
				}
				else if (x == x->p->right)
				{
					x = x->p;
					Left_Rotate(T, x);
				}
				x->p->color = 'B';
				x->p->p->color = 'R';
				Right_Rotate(T, x->p->p);
			}
			else
			{
				Node *y = x->p->p->left;
				if (y->color == 'R')
				{
					x->p->color = 'B';
					x->p->p->left->color = 'B';
					x->p->p->color = 'R';
					x = x->p->p;
				}
				else if (x == x->p->left)
				{
					x = x->p;
					Right_Rotate(T, x);
				}
				x->p->color = 'B';
				x->p->p->color = 'R';
				Left_Rotate(T, x->p->p);
			}
			T->color = 'B';
		}
	}
	void RB_Transplant(Node *&T, Node *&u, Node *&v)
	{
		if (u->p == nil)
			T = v;
		else if (u == u->p->left)
			u->p->left = v;
		else if (u == u->p->right)
			u->p->right = v;
		v->p = u->p;
	}
	void RB_Delete(Node *&T, Node *&x)
	{
		Node *y = x;
		y->color = x->color;
		if (x->left == nil)
		{
			Node *m = x->right;
			RB_Transplant(T, x, m);
		}
		else if (x->right == nil)
		{
			Node *m = x->left;
			RB_Transplant(T, x, m);
		}
		else
		{
			Node *n = Tree_MIN(x->right);
			y->color = n->color;
			Node *m = n->right;
			if (n->p == x)//出现这种情况的时候,是一个直线的情况,else中的句子会有问题,所以要改变一点
				m->p = n;
			else
			{
				RB_Transplant(T, n, n->right);
				n->right = x->right;
				x->right->p = n;
			}
			RB_Transplant(T, x, n);
			n->left = x->left;
			x->left->p = x;
			n->color = x->color;
			if (y->color = 'B')
				RB_Delete_Fixup(T, m);
		}
	}
	void RB_Delete_Fixup(Node*&T, Node*&x)
	{
		while (x!=T&&x->color=='B')
		{
			if (x == x->p->left)
			{
				Node* w = x->p->right;
				if (w->color == 'R')
				{
					w->color = 'B';
					x->p->color = 'R';
					Left_Rotate(T, x->p);
					w = x->p->right;
				}
				if (w->left->color == 'B'&&w->right->color == 'B')
				{
					w->color = 'R';
					x = x->p;
				}
				else if (w->right->color == 'B')
				{
					w->left->color = 'B';
					w->color = 'R';
					Right_Rotate(T, w);
					w = x->p->right;
				}
				w->color = 'R';
				x->p->color = 'B';
				Left_Rotate(T, x->p);
				w->right->color = 'B';
				x = T;
			}
			else
			{
				Node* w = x->p->left;
				if (w->color == 'R')
				{
					w->color = 'B';
					x->p->color = 'R';
					Right_Rotate(T, x->p);
					w = x->p->left;
				}
				if (w->right->color == 'B'&&w->left->color == 'B')
				{
					w->color = 'R';
					x = x->p;
				}
				else if (w->left->color == 'B')
				{
					w->right->color = 'B';
					w->color = 'R';
					Left_Rotate(T, w);
					w = x->p->left;
				}
				w->color = 'R';
				x->p->color = 'B';
				Right_Rotate(T, x->p);
				w->left->color = 'B';
				x = T;
			}
		}
		x->color = 'B';
	}
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值