算法导论-----红黑树

/*
红黑树的性质:
1、每个结点或是红色,或是黑色
2、根结点是黑色
3、如果一个结点是红色,则它的两个子结点都是黑色
4、对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点
5、所有叶子结点都是黑色
*/
#include "iostream"
using namespace std;

typedef enum  node_color
{
	BLACK,
	RED
}NODECOLOR;
typedef struct Node
{
	int    value;
	struct Node* parent;
	struct Node* left;
	struct Node* right;
	NODECOLOR    color;
}NODE,*NODE_POINT;


class  Tree
{
private:

	NODE_POINT     root;
	NODE_POINT*    EMPTY;
	void LEFT_ROTATE(NODE_POINT   x);
	void RIGHT_ROTATE(NODE_POINT  y);
	//插入时保持红黑性质
	void RB_INSERT_FIXUP(NODE_POINT z);
	//替换过程
	void RB_TRANSPLANT(NODE_POINT u,NODE_POINT v);
	//删除时保持红黑性质
	void RB_DELETE_FIXUP(NODE_POINT  x);
	//删除所有结点
	void  DELETE_ALL_NODE(NODE_POINT node);
public:
	Tree();
	~Tree();
	NODE_POINT  MINIMUM(NODE_POINT x);
	NODE_POINT  MAXIMUM(NODE_POINT x);
	NODE_POINT  MAXIMUM();
	NODE_POINT  MINIMUM();
	NODE_POINT  SEARCH(NODE_POINT x,int k);
	NODE_POINT  SEARCH(int k);
	NODE_POINT  SUCCESSOR(NODE_POINT node);
	void  INSERT_NODE(int  x);
	void  DELETE_NODE(int  x);
	
};

void Tree::DELETE_ALL_NODE(NODE_POINT node)
{
	if(node!=NULL)
	{
		DELETE_ALL_NODE(node->left);
		if(node->right!=NULL)
		{
			DELETE_ALL_NODE(node->right);
		}
		free(node);
		node=NULL;
	}
}
Tree::~Tree()
{
	DELETE_ALL_NODE(root);
}
Tree::Tree():root(NULL),EMPTY(NULL)
{
	EMPTY=(NODE_POINT*)malloc(sizeof(NODE));
	*EMPTY=NULL;
}

NODE_POINT Tree::MAXIMUM()
{
	return MAXIMUM(root);
}

NODE_POINT Tree::MINIMUM()
{
	return MINIMUM(root);
}
void Tree::RB_DELETE_FIXUP(NODE_POINT x)
{
	while (x!=root&&x->color==BLACK)
	{
		if(x==x->parent->left)
		{
				/*
				当x为其父结点的左孩子时,删除结点会有以下四种情况
				1、x的兄弟结点node是红色
				2、x的兄弟结点node是黑色,而且node的两个子结点都是黑色
				3、x的兄弟结点node是黑色,node的左孩子是红色,node的右孩子是黑色
				4、x的兄弟结点node是黑色,且node的右孩子是红色

				x是取代要删除的结点的结点,当x为其父结点的右孩子时,情况类似(颠倒左右)
				*/
			NODE_POINT  node=x->parent->right;
			//情况1,左旋可转变为情况2、3、4
			if(node->color==RED)
			{
				node->color=BLACK;
				x->parent->color=RED;
				LEFT_ROTATE(x->parent);
				node=x->parent->right;
			}

			
			if(node->left==NULL)
			{
				//情况2
				if(node->right==NULL||node->right->color==BLACK)
				{
					node->color=RED;
				//	RIGHT_ROTATE(node);
					x=x->parent;//
				}
			}
			else
			{
				//情况2
				if(node->right==NULL)
				{
					if(node->left->color==BLACK)
					{
						node->color=RED;
					//	RIGHT_ROTATE(node);
						x=x->parent;//
					}
				}
				//情况2
				else if(node->right->color==BLACK&&node->left->color==BLACK)
				{
					node->color=RED;
				//	RIGHT_ROTATE(node);
					x=x->parent;//
				}
				else
				{
					//情况3,可右旋变为情况4
					if(node->right->color==BLACK)
					{
						node->left->color=BLACK;
						node->color=RED;
						RIGHT_ROTATE(node);
						node=x->parent->right;
					}

					//情况4
					node->color=x->parent->color;
					x->parent->color=BLACK;
					LEFT_ROTATE(x->parent);

					x=root;
				}
			}
		}
		else
		{
			NODE_POINT  node=x->parent->left;
			//情况1,右旋可转变为情况2、3、4
			if(node->color==RED)
			{
				node->color=BLACK;
				x->parent->color=RED;
				RIGHT_ROTATE(x->parent);
				node=x->parent->right;
			}

			if(node->left==NULL)
			{
				//情况2
				if(node->right==NULL||node->right->color==BLACK)
				{
					node->color=RED;
				//	RIGHT_ROTATE(node);
					x=x->parent;//
				}
			}
			else
			{
				//情况2
				if(node->right==NULL)
				{
					if(node->left->color==BLACK)
					{
						node->color=RED;
				//		RIGHT_ROTATE(node);
						x=x->parent;//
					}
				}
				//情况2
				else if(node->right->color==BLACK&&node->left->color==BLACK)
				{
					node->color=RED;
				//	RIGHT_ROTATE(node);
					x=x->parent;//
				}
				else
				{
					//情况3,左旋变为情况4
					if(node->left->color==BLACK)
					{
						node->right->color=BLACK;
						node->color=RED;
						LEFT_ROTATE(node);
						node=x->parent->right;
					}

					//情况4,右旋
					node->color=x->parent->color;
					x->parent->color=BLACK;
					RIGHT_ROTATE(x->parent);

					x=root;
				}
			}
		}
	}
	x->color=BLACK;
}

void Tree::RB_TRANSPLANT(NODE_POINT u,NODE_POINT v)
{
	if(u->parent==NULL)
	{
		root=v;
	}
	else if(u==u->parent->left)
	{
		u->parent->left=v;
	}
	else
	{
		u->parent->right=v;
	}
	if(v!=NULL)
		v->parent=u->parent;
}
void Tree::DELETE_NODE(int k)
{
	NODE_POINT z,y,x;
	z=SEARCH(k);
	if(z==NULL)
	{
		printf("此红黑树中不存在该结点\n");
		return ;
	}
	else
	{
		y=z;
		//用来保存y的颜色
		NODECOLOR  color;
		color=y->color;
		if(z->left==NULL)
		{
			x=z->right;
			if(x==NULL)
			{
				//判断z是否为根结点
				if(z->parent==NULL)
				{
					free(root);
					root=NULL;
					z=NULL;
					return ;
				}
				else if(z==z->parent->right)
				{
					z->parent->right=NULL;
					z->parent=NULL;
					free(z);
					z=NULL;
				}
				else
				{
					z->parent->left=NULL;
					z->parent=NULL;
					free(z);
					z=NULL;
				}
				return;
			}
			RB_TRANSPLANT(z,x);
		}
		else if(z->right==NULL)
		{
			x=z->left;

			RB_TRANSPLANT(z,x);
		}
		else
		{
			//寻找z的后继结点
			y=SUCCESSOR(z);
			color=y->color;
			
			//如果y没有右孩子,说明它是叶结点,直接替换z就OK
			if(y->right==NULL)
			{
				if(y->parent!=z)
				{
					//用NULL代替y的位置
					RB_TRANSPLANT(y,NULL);
					
					y->right=z->right;
					y->right->parent=y;
				}
				RB_TRANSPLANT(z,y);
				y->left=z->left;
				y->left->parent=y;
				y->color=z->color;

				//删除z,释放空间
				z->left=NULL;
				z->right=NULL;
				z->parent=NULL;
				free(z);
				z=NULL;

				return ;

			}
			else
			{
				x=y->right;
			}
			
			if(y->parent==z)
			{
				x->parent=y;
			}
			else
			{
				RB_TRANSPLANT(y,x);
				y->right=z->right;
				y->right->parent=y;
			}
			RB_TRANSPLANT(z,y);
			y->left=z->left;
			y->left->parent=y;
			y->color=z->color;
		}

		if(color==BLACK)
			RB_DELETE_FIXUP(x);
	}

	if(*EMPTY)
	{
		delete *EMPTY;
		if(*EMPTY==root)
		{
			root=NULL;
		}
		*EMPTY=NULL;
	}

	z->left=NULL;
	z->right=NULL;
	z->parent=NULL;
	free(z);
	z=NULL;

}

void Tree::RB_INSERT_FIXUP(NODE_POINT z)
{
	if(z->parent!=NULL)
	{
		NODE_POINT   y;
		while(z!=root&&z->parent->color==RED)
		{
			if(z->parent==z->parent->parent->left)
			{
				if(root->right==NULL)
				{
					//如果z为其父结点的左孩子,则将原根结点变为它的右兄弟
					if(z==z->parent->left)
					{
						root=z->parent;
						z->parent->right=z->parent->parent;
						z->parent->right->parent=z->parent;
						z->parent->parent=NULL;
						z->parent->right->left=NULL;
						z->parent->right->color=RED;
						root->color=BLACK;

						return;
					}
					else
					{
						//如果z为其父结点的右孩子,将z变为根结点
						root=z;
						z->right=z->parent->parent;
						z->right->parent=z;
						z->right->left=NULL;
						z->right->color=RED;

						z->left=z->parent;
						z->left->parent=z;
						z->left->right=NULL;


						root->color=BLACK;

						return;
					}
				}
				
				y=z->parent->parent->right;

				/*
				此时会有三种情况:
				1、z的叔结点y是红色
				2、z的叔结点y是黑色,且z是一个右孩子
				3、z的叔结点y是黑色,且z是一个左孩子

				情况1可转变成情况2、3
				情况2可转变成情况3

				当x的父结点是x的祖父结点的右孩子时,情况类似(左右颠倒)
				*/
		
				//情况1,可转变成情况2或3
				if(y!=NULL&& y->color==RED)
				{
					z->parent->color=BLACK;
					y->color=BLACK;
					z->parent->parent->color=RED;
					z=z->parent->parent;
				}
				else
				{
					//情况2,可转变成情况3
					if(z==z->parent->right)
					{
						//z上移一层
						z=z->parent;
						//z左旋转,会下降一层
						LEFT_ROTATE(z);
					}

					//情况3
					//修正对性质3的违反,会破坏性质4
					z->parent->color=BLACK;
					z->parent->parent->color=RED;
					//保持性质4
					RIGHT_ROTATE(z->parent->parent);
				}
			}
			else
			{
				if(root->left==NULL)
				{
					//z为其父结点的右孩子,则原根结点为它的左兄弟
					if(z==z->parent->right)
					{
						root=z->parent;
						z->parent->left=z->parent->parent;
						z->parent->left->parent=z->parent;
						z->parent->parent=NULL;
						z->parent->left->right=NULL;
						z->parent->right->color=RED;
						root->color=BLACK;

						return;
					}
					else
					{
						//如果z为其父结点的左孩子,将z变为根结点
						root=z;
						z->left=z->parent->parent;
						z->left->parent=z;
						z->left->right=NULL;
						z->left->color=RED;

						z->right=z->parent;
						z->right->parent=z;
						z->right->left=NULL;

						root->color=BLACK;

						return;
					}
				}

				y=z->parent->parent->left;
				if(y!=NULL&&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(z);
					}
					z->parent->color=BLACK;
					z->parent->parent->color=RED;
					LEFT_ROTATE(z->parent->parent);
				}
			}
		}
	}
	root->color=BLACK;
}

void Tree::INSERT_NODE(int k)
{
	//树为空,插入的为根节点
	if(root==NULL)
	{
		root=(NODE_POINT)malloc(sizeof(NODE));

		root->value=k;
		root->parent=NULL;
		root->left=NULL;
		root->right=NULL;
		root->color=BLACK;
	}
	else
	{
		NODE_POINT  z;
		NODE_POINT  x,y;
		z=(NODE_POINT)malloc(sizeof(NODE));
		z->value=k;
		x=root;
		y=NULL;

		while(x!=NULL)
		{
			y=x;
			if(z->value<x->value)
			{
				x=x->left;
			}
			else
			{
				x=x->right;
			}
		}
		z->parent=y;

		if(y==NULL)
		{
			root=z;
		}
		else if(z->value<y->value)
		{
			y->left=z;
		}
		else
		{
			y->right=z;
		}

		z->left=NULL;
		z->right=NULL;
		z->color=RED;

		RB_INSERT_FIXUP(z);
	}
}

void Tree::RIGHT_ROTATE(NODE_POINT y)
{
	if(y->parent!=NULL)
	{
		NODE_POINT x;
		x=y->left;
		y->left=x->right;

		if(x->right!=NULL)
		{
			x->right->parent=y;
		}
		x->parent=y->parent;
		if(y->parent==NULL)
		{
			root=x;
		}
		else if(y==y->parent->left)
		{
			y->parent->left=x;
		}
		else
		{
			y->parent->right=x;
		}
		x->right=y;
		y->parent=x;
	}

}

void Tree::LEFT_ROTATE(NODE_POINT x)
{
	if(x->parent!=NULL)
	{
		NODE_POINT  y;
		y=x->right;
		x->right=y->left;

		if(y->left!=NULL)
		{
			y->left->parent=x;
		}
		y->parent=x->parent;

		//x为根结点情况
		if(x->parent==NULL)
		{
			root=y;
		}
		else if(x==x->parent->left)
		{
			x->parent->left=y;
		}
		else
		{
			x->parent->right=y;
		}

		y->left=x;
		x->parent=y;
	}
}


NODE_POINT Tree::SUCCESSOR(NODE_POINT  x)
{
	//右孩子不为空
	if(x->right!=NULL)
	{
		return MINIMUM(x->right);
	}
	else
	{
		NODE_POINT y;
		y=x->parent;
		//右孩子为空,且自身为父节点右孩子
		//(当为左孩子时,父节点为其后继节点,直接返回父节点)
		while(y!=NULL&&x==y->right)
		{
			//当x位于根节点的右子树中,y最终为NULL
			x=y;
			y=y->parent;
		}      


		return  y;
	}
}

NODE_POINT Tree::SEARCH(int k)
{
	return SEARCH(root,k);
}

NODE_POINT Tree::SEARCH(NODE_POINT x,int k)
{

	if(x==NULL||k==x->value)
	{
		return x;
	}
	if(k<(x->value))
	{
		return SEARCH(x->left,k);
	}
	else
	{ 
		return SEARCH(x->right,k);
	}
}


NODE_POINT   Tree::MINIMUM(NODE_POINT  x)
{
	if(x!=NULL)
	{
		while(x->left!=NULL)
		{
			x=x->left;
		}

	}

	return x;
}

NODE_POINT  Tree::MAXIMUM(NODE_POINT  x)
{


	if(x!=NULL)
	{
		while(x->right!=NULL)
		{
			x=x->right;
		}
	}

	return x;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值