码迷,mamicode.com
首页 > 编程语言 > 详细

算法导论 第十三章:红黑树

时间:2015-07-16 19:54:30      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:算法导论   红黑树   插入   删除   

红黑树(red-black tree)是一种“平衡”查找树,它能保证最坏情况下,基本的动态集操作时间为O(lgn).

性质:

1)每个节点要么是红的,要么是黑的

2)根节点和叶子节点(NIL)是黑色的

3)若一个节点是红色的,则他的两个孩子节点是黑色的

4)对于每一个节点x,从该节点到其子酸节点的所有路径上包含相同数目的黑节点(#black nodes = black-height(x))

引理:

    一棵有n个内节点的红黑树的高度至多为 2 lg(n+1)


红黑树上插入删除的完整代码如下:

#include<iostream>
#include<iomanip>
using namespace std;

#define BLACK 0
#define RED 1

typedef struct RBTNode{
	int key;
	bool color;
	RBTNode *parent;
	RBTNode *left;
	RBTNode *right;
	}RBTNode;

typedef struct RBTree{
	RBTNode *root;
	}RBTree;

RBTNode NILL={-1,BLACK,NULL,NULL,NULL};
RBTNode *NIL=&NILL;          //init sentinel NIL

void RBT_InorderWalk(RBTNode *x)
{
	if(x!=NIL)
	{
		RBT_InorderWalk(x->left);
		cout<<setw(3)<<x->key;
		if(x->color==1)
			cout<<"     Red"<<endl;
		else
			cout<<"     Black"<<endl;
		RBT_InorderWalk(x->right);
 		}
	}
RBTNode *RBT_Search(RBTNode *x,int key)
{
	if(x->key == key || x==NIL)
		return x;
	if(key < x->key)
		RBT_Search(x->left,key);
	else
		RBT_Search(x->right,key);
		}
RBTNode *RBT_Minimum(RBTNode *x)
{
	while(x->left != NIL)
		x=x->left;
	return x;
	
	}
void Left_Rotate(RBTree *T,RBTNode *x)
{
	RBTNode *y=x->right;    //set y

	x->right=y->left;       //turn y's left subtree into x's right subtree
	if(y->left!=NIL)
		y->left->parent=x;

	y->parent=x->parent;     //link x's parent to y;
	if(x->parent == NIL)
		T->root=y;
	else if(x==x->parent->left)
		x->parent->left=y;
	else
		x->parent->right=y;

	y->left=x;               //put x on y's left
	x->parent=y;
	}

void Right_Rotate(RBTree *T,RBTNode *x)
{
	RBTNode *y=x->left;      //set y
	
	x->left=y->right;   //link x's left tree into y's right subtree;
	if(y->right !=NIL)
		y->right->parent=x;
	
	y->parent=x->parent;    //link x's parent to y
	if(x->parent == NIL)
		T->root=y;
	else if(x == x->parent->left)
		x->parent->left=y;
	else
		x->parent->right=y;
	
	y->right=x;         //put x on y's right
	x->parent=y;

	}
void RBT_InsertFixup(RBTree *T,RBTNode *z)
{
	while(z->parent->color==RED)
	{
		if(z->parent == z->parent->parent->left)    
		{
			RBTNode *y=z->parent->parent->right;   
			if(y->color==RED)
			{  
				z->parent->color=BLACK;            //case 1
				y->color=BLACK;                    //case 1
				z->parent->parent->color=RED;      //case 1
				z=z->parent->parent;               //case 1
				}
			else
			{
			   	if(z==z->parent->right)
				{ 
					z=z->parent;                    //case 2
					Left_Rotate(T,z);               //case 2
				 	}
				z->parent->color=BLACK;             //case 3
				z->parent->parent->color=RED;       //case 3
				Right_Rotate(T,z->parent->parent);  //case 3
		 		} 
		 	}
		else
		{//ame as then clause with "right" and "left" exchanged  
			RBTNode *y=z->parent->parent->left;
			if(y->color==RED)
			{
				z->parent->color==BLACK;
				y->color=BLACK;
				z->parent->parent->color=RED;
				z=z->parent->parent;
		 		}
			else
			{
				if(z==z->parent->left)
				{
					z=z->parent;
					Right_Rotate(T,z);
				 	}
				z->parent->color=BLACK;
				z->parent->parent->color=RED;
				Left_Rotate(T,z->parent->parent);
			 	} 
			} 
		} 
	T->root->color=BLACK;      //turn the root to BLACK
	}
void RBT_Insert(RBTree *T,int value)
{
	RBTNode *z=new RBTNode();
	z->key=value;
	z->color =RED;   
	z->parent=NIL;
	z->left=NIL;
	z->right=NIL;

	RBTNode *y=NIL;        //y is the parent of x
	RBTNode *x=T->root;
	while(x != NIL)
	{
		y=x;
		if(z->key < x->key)
			x=x->left;
		else
			x=x->right;
		}  
	z->parent=y;   //link new node's parent node to y(y's child is NIL)
	if(y==NIL)
		T->root=z;
	else if(z->key < y->key)
		y->left=z;
	else
		y->right =z;
	RBT_InsertFixup(T,z);
	}

void RBT_Transplant(RBTree *T,RBTNode *u,RBTNode *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;
	}
void RBT_DeleteFixup(RBTree *T,RBTNode *x)
{
	RBTNode *w;
	while(x!=T->root && x->color==BLACK)
	{
		if(x==x->parent->left)
	 	{
			w=x->parent->right;  //set w to x's sibling
			if(w->color==RED)      //case 1:x's sibling w is red
			{
				w->color=BLACK;
				x->parent->color=RED;
				Left_Rotate(T,x->parent);
				w=x->parent->right;
	 			}
			if(w->left->color==BLACK && w->right->color==BLACK)  
			{ //case 2:x's sibling w is black and both of w's children are black
				w->color=RED;
				x=x->parent;
				}
			else
			{ 
				if(w->right->color==BLACK)     
				{//case 3:x's sibling w is black,w's left child is red, and w's right child is black
					w->left->color=BLACK;
					w->color=RED;
					Right_Rotate(T,w);
					w=x->parent->right;
			 		}
				w->color=x->parent->color;      //case 4: x's sibling w is black,and w's right child is red
				x->parent->color=BLACK;         //.
				w->right->color=BLACK;         // .
				Left_Rotate(T,x->parent);      // .
				x=T->root;                     //case 4
				}
			}
		else
		{//Same as then clause with "right" and "left" exchanged
			w=x->parent->left;
			if(w->color==RED)
			{
				w->color=BLACK;
				x->parent->color=RED;
				Right_Rotate(T,x->parent);
				w=x->parent->left;
				} 
			if(w->left->color==BLACK && w->right->color==BLACK)
			{ 
				w->color=RED;
				x=x->parent;
				}
			else
			{
				if(w->left->color==BLACK)
				{
					w->right->color=BLACK;
					w->color=RED;
					Left_Rotate(T,w);
					w=x->parent->left;
			 	 	}
				w->color=x->parent->color;
				x->parent->color=BLACK;
				w->left->color=BLACK;
				Right_Rotate(T,x->parent);
				x=T->root;
	 			} 
	 		}
  		}
 	x->color=BLACK;
	}
/*RBTNode *RBT_Successor(RBTNode *x){
     RBTNode *r = x;
     if(r->right != NIL)
         return RBT_Minimum(r->right);
     RBTNode *y = r->parent;
     while(y != NIL && r  == y->right){
         r = y;
         y = y->parent;
     }
     return y;
 }*/
void RBT_Delete(RBTree *T,RBTNode *z)
{
	RBTNode *x=NULL,*y=NULL;
	bool y_origin_color;

	y=z;
	y_origin_color=y->color;
	if(z->left == NIL)
	{
		x=z->right;
		RBT_Transplant(T,z,z->right);
	 	}
	else if(z->right ==NIL)
	{ 
		x=z->left;
		RBT_Transplant(T,z,z->left);
	  	}
	else
	{ 
		y=RBT_Minimum(z->right);
		y_origin_color=y->color;
		x=y->right;

		if(y->parent==z)
			x->parent=y;
		else
		{
			RBT_Transplant(T,y,y->right);
			y->right=z->right;
			y->right->parent=y;
	 		}
		RBT_Transplant(T,z,y);
		y->left=z->left;
		y->left->parent=y;
		y->color=z->color;
	  	}
	if(y_origin_color==BLACK)
		RBT_DeleteFixup(T,x);
		}

int main()
{
	int A[]={41,38,31,12,19,8};
	int n=sizeof(A)/sizeof(int);
	
	cout<<"/*--------------------Ceate Red-Black tree------------------*/"<<endl;
	RBTree *T=new RBTree();
	T->root=NIL;
	for(int i=0;i<n;i++)
		RBT_Insert(T,A[i]);
	cout<<"The Red-Black tree is:"<<endl;
	RBT_InorderWalk(T->root);
	cout<<"The root of the RBT is:"<<T->root->key<<endl;
	cout<<"/*----------------------------------------------------------*/"<<endl;

	cout<<"/*----------------------RBT Insertion-----------------------*/"<<endl;
	int ikey;
	cout<<"Please input the inserting key:";
	cin>>ikey;
	RBT_Insert(T,ikey);
	cout<<"After insertion,the RBT is:"<<endl;
	RBT_InorderWalk(T->root);
	cout<<"The root of the RBT is:"<<T->root->key<<endl;
	cout<<"/*-----------------------------------------------------------*/"<<endl;

	cout<<"/*---------------------RBT Deletion-------------------------*/"<<endl;
	int dkey;
	cout<<"Please input the deleting key:";
	cin>>dkey;
	RBTNode *dNode=NULL;
	dNode=RBT_Search(T->root,dkey);
	if(dNode==NULL)
		cout<<"The deleting key doesn't exist."<<endl;
	else
	{
		RBT_Delete(T,dNode);
		cout<<"After deletion,the RBT is:"<<endl;
		RBT_InorderWalk(T->root);
		cout<<"The root of the RBT is:"<<T->root->key<<endl;
		}

	return 0;
	}

运行结果如下:

技术分享


版权声明:本文为博主原创文章,未经博主允许不得转载。

算法导论 第十三章:红黑树

标签:算法导论   红黑树   插入   删除   

原文地址:http://blog.csdn.net/u010183397/article/details/46914789

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!