RED-BLACK TREES(红黑树)--算法导论

        红黑树(red-black tree)是许多“平衡”搜索树中的一种,可以保证在最坏的情况下基本动态集合操作的时间复杂度为O(\log_{2}n).。在了解红黑树之前你得先了解二叉搜索树。

一,红黑树的性质

        红黑树是一颗二叉搜索树,它在每个结点上增加了一个存储位来表示结点的颜色,可以是RED或BLACK。通过任何一条从根到叶子的简单路径上各个结点的颜色进行约束,红黑树确保没有一条路径会比其他路径长出两倍,因而是平衡的。

         一颗红黑树是满足下面红黑性质的二叉搜索树:

1.每个结点或是红色的,或是黑色的

2.根结点是黑色的

3.每个叶节点(NULL)是黑色的

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

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

        从某个结点x出发到达一个叶节点的任意一条简单路径上的黑色结点个数称为该节点的黑高(black-height),记bh。

证:n个结点的红黑树高度至多为2\log_{2}(n+1)

        综上可知,红黑树的搜索效率可一直保持在O(\log_{2}n)

二,插入

        搜索树操作TREE-INSERT和TREE-DELETE在含n个关键字的红黑树上,运行时间花费时间为O(\log_{2}n),由于这两个操作对树进行了修改,结果可能违反红黑性质。为了维护这些性质,必须要改变树中某些结点的颜色和指针结构。

      

        插入一个结点时,我们将插入的结点颜色定义为红色,如果定义为黑色就违反了性质5每条路径的黑色结点个数相同。

        因为新节点的默认颜色是红色,因此如果其双亲节点的颜色是黑色,没有违反红黑树任何性质,则不需要调整;但当新插入节点的双亲节点颜色为红色时,就违反了性质4不能有连在一起的红色节点,此时需要对红黑树分情况来讨论:

        在右边的话同理,将步骤反过来即可

变换主要看叔叔结点的颜色和路径是否是折线。

    三,删除    

        与n个结点的红黑树上的其他基本操作一样,删除一个结点要花费O(\log_{2}n)。与插入操作相比,删除操作要稍微复杂写。

        删除操作的被删出元素的颜色对红黑性质没有多大影响,因为我们使顶替它位置的元素的颜色变成被删除元素的颜色,如果顶替元素是红色,可直接变,不会影响性质5(每条路径有相同数量的黑结点)。如果是黑色,那么顶替元素的路径会少一个黑色结点,违反了性质5。我们要通过旋转和改变颜色的操作来恢复红黑性质。

实现:

为了便于处理红黑树代码中的边界条件,使用一个哨兵来代表NULL。对于一颗红黑树T,哨兵NIL是一个与树中普通节点有相同的属性对象。它的color属性为BLACK,其他属性可以设任意值。

#include<iostream>
using namespace std;
#include<stdlib.h>

enum COLOR{RED,BLACK};
typedef struct BSTNode
{
	int data;
	struct BSTNode* left;
	struct BSTNode* right;
	struct BSTNode* parent;
	COLOR color;

}Node;
//哨兵位
Node* NIL = (Node*)malloc(sizeof(Node));
typedef struct RBTree
{
	Node* root=NIL;
}RBT;

void RB_INSERT_FIXUP(RBT&T, Node*z);
//左旋
void LEFT_ROTOTE(RBT& T, Node* p);
// 右旋
void RIGHT_ROTOTE(RBT& T, Node* p);
//插入
void RBTree_Insert(RBT &T,int x)
{
	//找到元素的位置插入
	Node* z = T.root;
	Node* pre = NULL;
	while (z != NIL)
	{
		pre = z;
		if (x < z->data)
			z = z->left;
		else
			z = z->right;
	}
	if (pre == NULL)
	{
		T.root = (Node*)malloc(sizeof(Node));
		T.root->data = x;
		T.root->color = BLACK;
		T.root->parent = NIL;
		T.root->left = NIL;
		T.root->right = NIL;
		z = T.root;
	}
	else if(x<pre->data)
	{
		pre->left = (Node*)malloc(sizeof(Node));
		pre->left->data = x;
		pre->left->color = RED;
		pre->left->parent = pre;
		pre->left->left = NIL;
		pre->left->right = NIL;
		z = pre->left;
	}
	else
	{
		pre->right = (Node*)malloc(sizeof(Node));
		pre->right->data = x;
		pre->right->color = RED;
		pre->right->parent = pre;
		pre->right->left = NIL;
		pre->right->right = NIL;
		z = pre->right;
	}
	//利用旋转和改变颜色保持红黑性质

		RB_INSERT_FIXUP(T, z);

	
}
void RB_INSERT_FIXUP(RBT& T, Node* z)
{
	Node* u;
	while (z->parent->color == RED)       //父结点为红色,出现红红
	{
		if (z->parent = z->parent->parent->left)   //找叔叔节点
		{
			u = z->parent->parent->right;
			if (u->color == RED)                  //叔叔结点为红,将父结点和叔叔结点变黑,组父结点变红
			{
				z->parent->color = BLACK;
				u->color = BLACK;
				z->parent->parent->color = RED;
				z = z->parent->parent;

			}
			else if (z == z->parent->right)      //叔叔是黑,就观察路径是否是折线
			{
				LEFT_ROTOTE(T, z);
				z->color = BLACK;
				z->parent->color = RED;
				RIGHT_ROTOTE(T, z);
			}
			else
			{
				z->parent->color = BLACK;
				z->parent-> parent->color = RED;
				RIGHT_ROTOTE(T, z->parent);
			}
		}
		else
		{
			u = z->parent->parent->left;
			if (u->color == RED)
			{
				z->parent->color = BLACK;
				u->color = BLACK;
				z->parent->parent->color = RED;
				z = z->parent->parent;
			}
			else if (z == z->parent->left)
			{
				RIGHT_ROTOTE(T, z);
				z->color = BLACK;
				z->parent->color = RED;
				LEFT_ROTOTE(T, z);
			}
			else
			{
				z->parent->color = BLACK;
				z->parent->parent->color = RED;
				LEFT_ROTOTE(T, z->parent);
			}
		}
		T.root->color = BLACK;
	}
}
//左旋
void LEFT_ROTOTE(RBT& T, Node* p)
{
	Node* g = p->parent;
	//交换
	if (g->parent == NIL)
	{
		T.root = p;
		p->parent = NIL;
	}
	else
	{
		if (g == g->parent->left)
		{
			g->parent->left = p;
			p->parent = g->parent;
		}
		else
		{
			g->parent->right = p;
			p->parent = g->parent;
		}
	}
	g->parent = p;
	g->right = p->left;
	if (p->left!=NIL)
		p->left->parent = g;
	p->left = g;
	
	
}
// 右旋
void RIGHT_ROTOTE(RBT& T, Node* p)
{
	Node* g = p->parent;
	//交换
	if (g->parent == NIL)
	{
		T.root = p;
		p->parent = NIL;
	}
	else
	{
		if (g == g->parent->left)
		{
			g->parent->left = p;
			p->parent = g->parent;
		}
		else
		{
			g->parent->right = p;
			p->parent = g->parent;
		}
	}
	g->parent = p;
	g->left = p->right;
	if (p->right!=NIL)
		p->right->parent = g;
	p->right = g;
	
	
}
//交换元素
void RB_TRANSPLANT(RBT &T, Node* u, Node* v)
{
	if (u->parent == NIL)
	{
		T.root = v;
	}
	else if (u == u->parent->left)
	{
		u->parent->left = v;
	}
	else
	{
		u->parent->right = v;
	}
	
	v->parent = u->parent;

}
//找最大值
Node* RB_MINIMUM(Node* T)
{
	Node* cur = T;
	Node* pre = NIL;
	while (cur!=NIL)
	{
		pre = cur;
		cur = cur->left;
	}
	return pre;
}
//改变颜色和旋转操作
void RB_DELETE_FIXUP(RBT &T, Node* x);
//删除
void RB_DELETE(RBT &T, int data)
{
	Node* x;
	Node* y;
	//找元素位置
	Node* cur = T.root;
	while (cur->data != data)
	{
		if (data < cur->data)
			cur = cur->left;
		else
			cur = cur->right;

	}
	//删除
	
	 y = cur;
	COLOR y_color = cur->color;
	if (cur->left == NIL)
	{
		 x = cur->right;
		RB_TRANSPLANT(T, cur, x);
	}
	else if (cur->right == NIL)
	{
		 x = cur->left;
		RB_TRANSPLANT(T, cur, x);
	}
	else
	{
		y = RB_MINIMUM(cur->right);
		y_color = y->color;
		 x = y->right;
		if (y->parent == cur)
		{
			x->parent = y;
		}
		else
		{
			RB_TRANSPLANT(T, y, x);
			y->right = cur->right;
			y->right->parent = y;
		}
		RB_TRANSPLANT(T, cur, y);
		y->left = cur->left;
		y->left->parent = y;
		y->color = cur->color;
	}
	//恢复红黑性质
	if (y_color == BLACK)
		RB_DELETE_FIXUP(T,x);
	free(cur);
}
//改变颜色和旋转操作
void RB_DELETE_FIXUP(RBT& T, Node* x)
{
	
		
	
		while (x != T.root && x->color == BLACK)  //有双重黑色进行修复
		{
			Node* w;
			if (x == x->parent->left)        //找兄弟节点
			{
				w = x->parent->right;
				if (w->color == RED)          //情况4
				{
					w->color = BLACK;
					w->parent->color = RED;
					LEFT_ROTOTE(T, w);
					w = x->parent->right;

				}
				if (w->left->color == BLACK && w->right->color == BLACK)//情况3
				{
					w->color = RED;
					if (w->parent->color == RED)     //父结点为红色,则直接覆盖,没有双重黑色,可退出循环
						x = T.root;
					else
						x = x->parent;
					w->parent->color = BLACK;
				}
				else if (w->left->color == RED && w->right->color == BLACK)//情况2
				{
					w->left->color = BLACK;
					w->color = RED;
					RIGHT_ROTOTE(T, w->left);
					w = x->parent->right;
				}
				if (w->right->color == RED)//情况1
				{
					w->color = w->parent->color;
					w->parent->color = BLACK;
					w->right->color = BLACK;
					LEFT_ROTOTE(T, w);
					x = T.root;
				}
				
			}
			else          //同理只要将left与right互换即可
			{
				w = x->parent->left;
				if (w->color == RED)
				{
					w->color = BLACK;
					w->parent->color = RED;
					RIGHT_ROTOTE(T, w);
					w = x->parent->left;
				}
				if (w->left->color == BLACK && w->right->color == BLACK)
				{
					w->color = RED;
					if (w->parent->color == RED)
						x = T.root;
					else
						x = x->parent;
					w->parent->color = BLACK;
				}
				else if (w->right->color == RED && w->left->color == BLACK)
				{
					w->right->color = BLACK;
					w->color = RED;
					LEFT_ROTOTE(T, w->right);
					w = x->parent->left;
				}
				if (w->left->color == RED)
				{
					w->color = w->parent->color;
					w->parent->color = BLACK;
					w->left->color = BLACK;
					RIGHT_ROTOTE(T, w);
					x = T.root;
				}
			}
		}

		x->color = BLACK;

}
//层序遍历
#include"Queue.h"
void LevalOrder(RBT& T)
{
	Node* p = T.root;
	queue q;
	InitQueue(q);
	PushQueue(q, p);
	int i = q.tail - q.head;
	while (!QueueEmpty(q))
	{
		Node* cur;
		
		GetQueue(q, cur);
		PopQueue(q);
		cout << cur->data ;
		if (cur->left!=NIL)
			cout << "["<<cur->left->data << "]";
		else
			cout << "[NULL]";
		if (cur->right!=NIL)
			cout <<"["<< cur->right->data << "]";
		else
			cout << "[NULL]" ;
		if (cur->color == RED)
			cout << "[RED]  " ;
		else
			cout << "[BLACK]  ";
		--i;
		if (cur->left!=NIL)
			PushQueue(q, cur->left);
		if (cur->right!=NIL)
			PushQueue(q, cur->right);
		if (i == 0)
		{
			cout << endl;
			i = q.tail - q.head;
		}
	}

}
int main()
{
	RBT rb;
	NIL->color = BLACK;
	RBTree_Insert(rb, 17);
	RBTree_Insert(rb, 16);
	RBTree_Insert(rb, 15);
	RBTree_Insert(rb, 14);
	RBTree_Insert(rb, 13);
	RBTree_Insert(rb, 12);
	RBTree_Insert(rb, 11);
	RBTree_Insert(rb, 10);
	RBTree_Insert(rb, 9);
	RBTree_Insert(rb, 8);
	RBTree_Insert(rb, 7);
	RBTree_Insert(rb, 6);
	RBTree_Insert(rb, 5);
	RBTree_Insert(rb, 4);
	RBTree_Insert(rb, 3);
	RBTree_Insert(rb, 2);
	RBTree_Insert(rb, 1);
	cout << endl;

	cout << "红黑树排有序数组的层序遍历结果:" << endl;
	LevalOrder(rb);
	cout << endl;
	RB_DELETE(rb, 2);
	cout << "删除元素2后的层序遍历结果:" << endl;
	LevalOrder(rb);
	cout << endl;
	RB_DELETE(rb, 8);
	cout << "删除元素8后的层序遍历结果:" << endl;
	LevalOrder(rb);
	cout << endl;
	RB_DELETE(rb, 9);
	cout << "删除元素9后的层序遍历结果:" << endl;
	LevalOrder(rb);
	cout << endl;
	RB_DELETE(rb, 3);
	cout << "删除元素3后的层序遍历结果:" << endl;
	LevalOrder(rb);
	cout << endl;
	RB_DELETE(rb, 11);
	cout << "删除元素11后的层序遍历结果:" << endl;
	LevalOrder(rb);
	cout << endl;
	RB_DELETE(rb, 6);
	cout << "删除元素6后的层序遍历结果:" << endl;
	LevalOrder(rb);
	RB_DELETE(rb, 13);
	cout << endl;

	cout << "删除元素13后的层序遍历结果:" << endl;
	LevalOrder(rb);
	RB_DELETE(rb, 4);
	cout << endl;

	cout << "删除元素4后的层序遍历结果:" << endl;
	LevalOrder(rb);
	RB_DELETE(rb, 1);
	cout << endl;

	cout << "删除元素1后的层序遍历结果:" << endl;
	LevalOrder(rb);
	RB_DELETE(rb, 5);
	cout << endl;

	cout << "删除元素5后的层序遍历结果:" << endl;
	LevalOrder(rb);
	RB_DELETE(rb, 10);
	cout << endl;

	cout << "删除元素10后的层序遍历结果:" << endl;
	LevalOrder(rb);
	RB_DELETE(rb, 14);
	cout << endl;
	cout << "删除元素14后的层序遍历结果:" << endl;
	LevalOrder(rb);
	
	


	free(NIL);
}
红黑树排有序数组的层序遍历结果:
14[10][16][BLACK]
10[6][12][RED]  16[15][17][BLACK]
6[4][8][BLACK]  12[11][13][BLACK]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]
4[2][5][RED]  8[7][9][RED]  11[NULL][NULL][BLACK]  13[NULL][NULL][BLACK]
2[1][3][BLACK]  5[NULL][NULL][BLACK]  7[NULL][NULL][BLACK]  9[NULL][NULL][BLACK]
1[NULL][NULL][RED]  3[NULL][NULL][RED]

删除元素2后的层序遍历结果:
14[10][16][BLACK]
10[6][12][RED]  16[15][17][BLACK]
6[4][8][BLACK]  12[11][13][BLACK]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]
4[3][5][RED]  8[7][9][RED]  11[NULL][NULL][BLACK]  13[NULL][NULL][BLACK]
3[1][NULL][BLACK]  5[NULL][NULL][BLACK]  7[NULL][NULL][BLACK]  9[NULL][NULL][BLACK]
1[NULL][NULL][RED]

删除元素8后的层序遍历结果:
14[10][16][BLACK]
10[6][12][RED]  16[15][17][BLACK]
6[4][9][BLACK]  12[11][13][BLACK]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]
4[3][5][RED]  9[7][NULL][BLACK]  11[NULL][NULL][BLACK]  13[NULL][NULL][BLACK]
3[1][NULL][BLACK]  5[NULL][NULL][BLACK]  7[NULL][NULL][RED]
1[NULL][NULL][RED]

删除元素9后的层序遍历结果:
14[10][16][BLACK]
10[6][12][RED]  16[15][17][BLACK]
6[4][7][BLACK]  12[11][13][BLACK]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]
4[3][5][RED]  7[NULL][NULL][BLACK]  11[NULL][NULL][BLACK]  13[NULL][NULL][BLACK]
3[1][NULL][BLACK]  5[NULL][NULL][BLACK]
1[NULL][NULL][RED]

删除元素3后的层序遍历结果:
14[10][16][BLACK]
10[6][12][RED]  16[15][17][BLACK]
6[4][7][BLACK]  12[11][13][BLACK]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]
4[1][5][RED]  7[NULL][NULL][BLACK]  11[NULL][NULL][BLACK]  13[NULL][NULL][BLACK]
1[NULL][NULL][BLACK]  5[NULL][NULL][BLACK]

删除元素11后的层序遍历结果:
14[6][16][BLACK]
6[4][10][RED]  16[15][17][BLACK]
4[1][5][BLACK]  10[7][12][BLACK]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]
1[NULL][NULL][BLACK]  5[NULL][NULL][BLACK]  7[NULL][NULL][BLACK]  12[NULL][13][BLACK]
13[NULL][NULL][RED]

删除元素6后的层序遍历结果:
14[7][16][BLACK]
7[4][12][RED]  16[15][17][BLACK]
4[1][5][BLACK]  12[10][13][BLACK]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]
1[NULL][NULL][BLACK]  5[NULL][NULL][BLACK]  10[NULL][NULL][BLACK]  13[NULL][NULL][BLACK]

删除元素13后的层序遍历结果:
14[7][16][BLACK]
7[4][12][BLACK]  16[15][17][BLACK]
4[1][5][RED]  12[10][NULL][BLACK]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]
1[NULL][NULL][BLACK]  5[NULL][NULL][BLACK]  10[NULL][NULL][RED]

删除元素4后的层序遍历结果:
14[7][16][BLACK]
7[5][12][BLACK]  16[15][17][BLACK]
5[1][NULL][BLACK]  12[10][NULL][BLACK]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]
1[NULL][NULL][RED]  10[NULL][NULL][RED]

删除元素1后的层序遍历结果:
14[7][16][BLACK]
7[5][12][BLACK]  16[15][17][BLACK]
5[NULL][NULL][BLACK]  12[10][NULL][BLACK]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]
10[NULL][NULL][RED]

删除元素5后的层序遍历结果:
14[10][16][BLACK]
10[7][12][BLACK]  16[15][17][BLACK]
7[NULL][NULL][BLACK]  12[NULL][NULL][BLACK]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]

删除元素10后的层序遍历结果:
14[12][16][BLACK]
12[7][NULL][BLACK]  16[15][17][RED]
7[NULL][NULL][RED]  15[NULL][NULL][BLACK]  17[NULL][NULL][BLACK]

删除元素14后的层序遍历结果:
15[12][16][BLACK]
12[7][NULL][BLACK]  16[NULL][17][BLACK]
7[NULL][NULL][RED]  17[NULL][NULL][RED]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值