算法导论复习:第十三章

1. 红黑树的性质

树中每个节点包含5个属性:color,key,left,right和p.如果一个节点没有子节点或父节点,则该节点相应指针属性的值为NIL.

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

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

2). 根节点是黑色的.

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

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

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


2. 旋转

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <limits.h>

typedef struct RBTREE{
	int						color;		//0为红,1为黑
	int						data;
	struct RBTREE		*lchild;
	struct RBTREE		*rchild;
	struct RBTREE		*parent;
}RBTree;

//左旋转
void leftRotate( RBTree *rbtree, RBTree *x );
//右旋转
void rightRotate( RBTree *rbtree, RBTree *y );
//插入结点
void rbInsert( RBTree *rbtree, int value );
//删除节点
int rbDelete( RBTree *rbtree, int value );
//查找结点
RBTree *rbSearch( RBTree *root, RBTree *rbtree, int value );
//打印红黑树
void rbShowTree( RBTree *rbtree );
//辅助插入结点着色函数
void rbInsertFixup( RBTree *rbtree, RBTree *z );
//辅助删除节点着色函数
void rbDeleteFixup( RBTree *rbtree, RBTree *x );
//将子树v移植到子树u中
void rbTransplant( RBTree *rbtree, RBTree *u, RBTree *v );
//红黑树中的最小值
RBTree *rbtreeMinimum( RBTree *root, RBTree *rbtree );
//红黑树的最大值
RBTree *rbtreeMaximum( RBTree *root, RBTree *rbtree );
//查找后继结点
RBTree *rbtreeSuccessor( RBTree *rbtree, RBTree *x );

int main( void )
{
	int			i = 0;
	RBTree *rbtree = ( RBTree * )malloc( sizeof( RBTree ) );
	RBTree *NIL = ( RBTree * )malloc( sizeof( RBTree ) );
	NIL->color = 1;
	NIL->data = INT_MIN;
	NIL->lchild = NIL->rchild = NIL->parent = NULL;
	rbtree->color = 0;
	rbtree->data = INT_MIN;
	rbtree->lchild = NIL;
	rbtree->rchild = rbtree->parent = NULL;

	rbInsert( rbtree, 11 );
	rbInsert( rbtree, 2 );
	rbInsert( rbtree, 14 );
	rbInsert( rbtree, 1 );
	rbInsert( rbtree, 7 );
	rbInsert( rbtree, 15 );
	rbInsert( rbtree, 5 );
	rbInsert( rbtree, 8 );
	rbInsert( rbtree, 4 );
	rbInsert( rbtree, 9 );

	printf("the tree is:\n");
	rbShowTree( rbtree->rchild );

	if ( rbtree->lchild != rbSearch( rbtree, rbtree, 5 ) ){
		printf("\n5 is in the tree\n");
	}
	else{
		printf("\n5 is not in the tree\n");
	}

	rbDelete( rbtree, 5 );
	rbDelete( rbtree, 7 );
	rbDelete( rbtree, 9 );
	printf("after delete, the tree is:\n");
	rbShowTree( rbtree->rchild );
	if ( rbtree->lchild != rbSearch( rbtree, rbtree, 5 ) ){
		printf("\n5 is in the tree\n");
	}
	else{
		printf("\n5 is not in the tree\n");
	}

	return 0;
}

void leftRotate( RBTree *rbtree, RBTree *x )
{
	RBTree *y = ( RBTree * )malloc( sizeof( RBTree ) );
	y = x->rchild;
	x->rchild = y->lchild;
	if ( y->lchild != rbtree->lchild ){
		y->lchild->parent = x;
	}
	y->parent = x->parent;
	if ( x->parent == rbtree->lchild ){
		rbtree->rchild = y;
	}
	else if ( x == x->parent->lchild ){
		x->parent->lchild = y;
	}
	else{
		x->parent->rchild = y;
	}
	y->lchild = x;
	x->parent = y;
}

void rightRotate( RBTree *rbtree, RBTree *y )
{
	RBTree *x = ( RBTree * )malloc( sizeof( RBTree ) );
	x = y->lchild;
	y->lchild = x->rchild;
	if ( x->rchild != rbtree->lchild ){
		x->rchild->parent = y;
	}
	x->parent = y->parent;
	if ( y->parent == rbtree->lchild ){
		rbtree->rchild = x;
	}
	else if ( y == y->parent->lchild ){
		y->parent->lchild = x;
	}
	else{
		y->parent->rchild = x;
	}
	x->rchild = y;
	y->parent = x;
}

void rbInsert( RBTree *rbtree, int value )
{
	RBTree *rbnewtree = ( RBTree * )malloc( sizeof( RBTree ) );
	rbnewtree->color = 0;
	rbnewtree->data = value;
	rbnewtree->lchild = rbnewtree->rchild = rbnewtree->parent = rbtree->lchild;

	if ( NULL == rbtree->rchild ){
		rbnewtree->color = 1;
		rbtree->rchild = rbnewtree;
	}
	else{
		RBTree *rbprevtree = ( RBTree * )malloc( sizeof( RBTree ) );
		RBTree *root = ( RBTree * )malloc( sizeof( RBTree ) );
		root = rbtree;
		rbtree = rbtree->rchild;
		rbprevtree = rbtree;
		while ( root->lchild != rbtree ){
			rbprevtree = rbtree;
			if ( value < rbtree->data ){
				rbtree = rbtree->lchild;
			}
			else{
				rbtree = rbtree->rchild;
			}
		}
		rbnewtree->parent = rbprevtree;
		if ( rbnewtree->data < rbprevtree->data ){
			rbprevtree->lchild = rbnewtree;
		}
		else{
			rbprevtree->rchild = rbnewtree;
		}
		rbInsertFixup( root, rbnewtree );
	}
}

void rbInsertFixup( RBTree *rbtree, RBTree *z )
{
	while ( 0 == z->parent->color ){
		if ( z->parent == z->parent->parent->lchild ){
			RBTree *y = ( RBTree * )malloc( sizeof( RBTree ) );
			y = z->parent->parent->rchild;
			if ( 0 == y->color ){
				z->parent->color = 1;
				y->color = 1;
				z->parent->parent->color = 0;
				z = z->parent->parent;
			}
			else if ( z == z->parent->rchild ){
				z = z->parent;
				leftRotate( rbtree, z );
			}
			else{
				z->parent->color = 1;
				z->parent->parent->color = 0;
				rightRotate( rbtree, z->parent->parent );
			}
		}
		else{
			RBTree *y = ( RBTree * )malloc( sizeof( RBTree ) );
			y = z->parent->parent->lchild;
			if ( 0 == y->color ){
				z->parent->color = 1;
				y->color = 1;
				z->parent->parent->color = 0;
				z = z->parent->parent;
			}
			else if ( z == z->parent->rchild ){
				z = z->parent;
				leftRotate( rbtree, z );
			}
			else{
				z->parent->color = 1;
				z->parent->parent->color = 0;
				rightRotate( rbtree, z->parent->parent );
			}
		}
	}
	rbtree->rchild->color = 1;
}

int rbDelete( RBTree *rbtree, int value )
{
	int			yOriginalColor;
	RBTree *x = ( RBTree * )malloc( sizeof( RBTree ) );
	RBTree *y = ( RBTree * )malloc( sizeof( RBTree ) );
	RBTree *z = ( RBTree * )malloc( sizeof( RBTree ) );
	z = rbSearch( rbtree, rbtree, value );
	if ( z == rbtree->lchild ){
		return 0;
	}
	y = z;
	yOriginalColor = y->color;
	if ( z->lchild == rbtree->lchild ){
		x = z->rchild;
		rbTransplant( rbtree, z, z->rchild );
	}
	else if ( z->rchild == rbtree->lchild ){
		x = z->lchild;
		rbTransplant( rbtree, z, z->lchild );
	}
	else{
		y = rbtreeSuccessor( rbtree, z );
		yOriginalColor = y->color;
		x = y->rchild;
		if ( y->parent == z ){
			x->parent = y;
		}
		else{
			rbTransplant( rbtree, y, y->rchild );
			y->rchild = z->rchild;
			y->rchild->parent = y;
		}
		rbTransplant( rbtree, z, y );
		y->lchild = z->lchild;
		y->lchild->parent = y;
		y->color = z->color;
	}

	if ( 1 == yOriginalColor ){
		rbDeleteFixup( rbtree, x );
	}

	return 1;
}

void rbTransplant( RBTree *rbtree, RBTree *u, RBTree *v )
{
	if ( u->parent == rbtree->lchild ){
		rbtree->rchild = v;
	}
	else if ( u == u->parent->lchild ){
		u->parent->lchild = v;
	}
	else{
		u->parent->rchild = v;
	}

	v->parent = u->parent;
}

RBTree *rbtreeMinimum( RBTree *root, RBTree *rbtree )
{
	while ( root->lchild != rbtree->lchild ){
		rbtree = rbtree->lchild;
	}

	return rbtree;
}

RBTree *rbtreeMaximum( RBTree *root, RBTree *rbtree )
{
	while ( root->lchild != rbtree->rchild ){
		rbtree = rbtree->rchild;
	}

	return rbtree;
}

RBTree *rbtreeSuccessor( RBTree *rbtree, RBTree *x )
{
	RBTree *y = ( RBTree * )malloc( sizeof( RBTree ) );
	if ( rbtree->lchild != x->rchild ){
		return rbtreeMinimum( rbtree, x->rchild );
	}
	y = x->parent;
	while ( rbtree->lchild != y && x == y->rchild ){
		x = y;
		y = y->parent;
	}

	return y;
}

RBTree *rbSearch( RBTree *root, RBTree *rbtree, int value )
{
	if ( root->lchild == rbtree || rbtree->data == value ){
		return rbtree;
	}
	if ( value < rbtree->data ){
		return rbSearch( root, rbtree->lchild, value );
	}
	else{
		return rbSearch( root, rbtree->rchild, value );
	}
}

void rbShowTree( RBTree *rbtree )
{
	if ( rbtree->data != INT_MIN ){
		rbShowTree( rbtree->lchild );
		printf("{%d:%s}  ", rbtree->data, rbtree->color ? "BLACK" : "RED" );
		rbShowTree( rbtree->rchild );
	}
}

void rbDeleteFixup( RBTree *rbtree, RBTree *x )
{
	while ( rbtree->lchild != x && x->color == 1 ){
		RBTree *w = ( RBTree * )malloc( sizeof( RBTree ) );
		if ( x == x->parent->lchild ){
			w = x->parent->rchild;
			if ( 0 == w->color ){
				w->color = 1;
				x->parent->color = 0;
				leftRotate( rbtree, x->parent );
				w = x->parent->rchild;
			}
			if ( 1 == w->lchild->color && 1 == w->rchild->color ){
				w->color = 0;
				x = x->parent;
			}
			else if ( 1 == w->rchild->color ){
				w->lchild->color = 1;
				w->color = 0;
				rightRotate( rbtree, w );
				w = x->parent->rchild;
			}
			else{
				w->color = x->parent->color;
				x->parent->color = 1;
				w->rchild->color = 1;
				leftRotate( rbtree, x->parent );
				x = rbtree->lchild;
			}
		}
		else{
			//我不能保证下面这个代码块是正确的,但是不知道如何举出测试的例子!!!
			w = x->parent->lchild;
			if ( 0 == w->color ){
				w->color = 1;
				x->parent->color = 0;
				rightRotate( rbtree, x->parent );
				w = x->parent->lchild;
			}
			if ( 1 == w->lchild->color && 1 == w->rchild->color ){
				w->color = 0;
				x = x->parent;
			}
			else if ( 1 == w->rchild->color ){
				w->lchild->color = 1;
				w->color = 0;
				leftRotate( rbtree, w );
				w = x->parent->rchild;
			}
			else{
				w->color = x->parent->color;
				x->parent->color = 1;
				w->rchild->color = 1;
				rightRotate( rbtree, x->parent );
				x = rbtree->lchild;
			}
		}
	}
	x->color = 1;
}



程序输出:



转载于:https://my.oschina.net/voler/blog/190557

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值