算法导论 练习题 14.3-6

#include <stdio.h>  
#include <stdlib.h>  
#include <limits.h>
#include <math.h>
#define RED 1  
#define BLACK 0  



typedef struct RBTreeNode  
{  
    int key;  
    int color;
	//节点增加3个域,以该节点为根的子树的最小值,最大值和最小gap值
	int min;
	int max;
	int minGap;
    RBTreeNode *p;  
    RBTreeNode *left;  
    RBTreeNode *right;  
}RBT,*pRBT;  
  
pRBT nil=(pRBT)malloc(sizeof(RBT));  
int bh=0;

void initNil()  
{  
    nil->key=-1;  
    nil->color=BLACK;  
    nil->p=NULL;  
    nil->left=NULL;  
    nil->right=NULL;  
	nil->min=INT_MAX;
	nil->max=INT_MIN;
	nil->minGap=INT_MAX;
}  

int min(int a,int b,int c,int d)
{
	if(a<=b && a<=c && a<=d)
		return a;
	else if(b<=c && b<=d)
		return b;
	else if(c<=d)
		return c;
	else
		return d;
}

int min2(int a,int b)
{
	return a<=b?a:b;
}

int max2(int a,int b)
{
	return a>=b?a:b;
}

void updateGap(pRBT x)
{
	if(!x || x==nil)
		return;
	//最小值为左子树最小值与该节点值中较小的一个,主要为了与nil比较时用
	x->min=min2(x->key,x->left->min);
	//最大值为右子树最大值与该节点值中较大的一个,主要为了与nil比较时用
	x->max=max2(x->key,x->right->max);
	int left1=x->left==nil?INT_MAX:x->key-x->left->max;
	int right1=x->right==nil?INT_MAX:x->right->min-x->key;
	//最小gap为左子树最小gap、右子树最小gap、key-左子树最大值、右子树最小值-key中最小的那个
	x->minGap=min(x->left->minGap,x->right->minGap,left1,right1);
}


void leftRotate(pRBT *root,pRBT x)  
{  
    //左旋要有右子树  
    if(x->right==nil)  
        return;  
    pRBT y=x->right;  
    x->right=y->left;  
    if(y->left != nil)  
        y->left->p=x;  
    y->p=x->p;  
    if(x->p==nil)  
    {  
        (*root)=y;  
    }  
    else if(x == x->p->left)  
    {  
        x->p->left=y;  
    }  
    else  
    {  
        x->p->right=y;  
    }  
    y->left=x;  
    x->p=y;  
	//修改新增域
	updateGap(x);
	updateGap(y);

}  


void rightRotate(pRBT *root,pRBT y)  
{  
    //右旋要有左子树  
    if(y->left==nil)  
        return;  
    pRBT x=y->left;  
    y->left=x->right;  
    x->p=y->p;  
	if(x->right != nil)
		x->right->p=y;
    if(y->p==nil)  
    {  
        (*root)=x;  
    }  
    else if(y==y->p->left)  
    {  
        y->p->left=x;  
    }  
    else  
    {  
        y->p->right=x;  
    }  
    x->right=y;  
    y->p=x;  
	//修改新增域
	updateGap(y);
	updateGap(x);
}  
  
void rbInsertFixup(pRBT *root,pRBT z)  
{  
    while(z->p->color==RED)  
    {  
        if(z->p==z->p->p->left)  
        {  
            pRBT y=z->p->p->right;  
            if(y->color==RED)  
            {  
                z->p->color=BLACK;  
                y->color=BLACK;  
                z->p->p->color=RED;  
                z=z->p->p;  
            }  
            else   
            {  
                if(z==z->p->right)  
                {  
                    z=z->p;  
                    leftRotate(root,z);  
                }  
                z->p->color=BLACK;  
                z->p->p->color=RED;  
                rightRotate(root,z->p->p);  
            }  
        }  
        else  
        {  
            pRBT y=z->p->p->left;  
            if(y->color==RED)  
            {  
                z->p->color=BLACK;  
                y->color=BLACK;  
                z->p->p->color=RED;  
                z=z->p->p;  
            }  
            else   
            {  
                if(z==z->p->left)  
                {  
                    z=z->p;  
                    rightRotate(root,z);  
                }  
                z->p->color=BLACK;  
                z->p->p->color=RED;  
                leftRotate(root,z->p->p);  
            }  
        }  
    }  
	if((*root)==nil || (*root)->color==RED)
		bh++;
	(*root)->color=BLACK;
	
}  
  
void rbInsert(pRBT *root,int key)  
{  
    pRBT z=(pRBT)malloc(sizeof(RBT));  
    z->key=key;  
    pRBT x=(*root);  
    pRBT y=nil;  
    while(x != nil)  
    {  
        y=x;  
        if(z->key<x->key)  
        {  
            x=x->left;  
        }  
        else  
        {  
            x=x->right;  
        }  
    }  
    z->p=y;  
    if(y==nil)  
    {  
        (*root)=z;  
    }  
    else if(z->key<y->key)  
    {  
        y->left=z;  
    }  
    else  
    {  
        y->right=z;  
    }  
    z->left=nil;  
    z->right=nil;  
    z->color=RED; 
	//从新增节点向上直到根节点,修改新增域
	pRBT u=z;
	while(u!=nil)
	{
		updateGap(u);
		u=u->p;
	}
    rbInsertFixup(root,z);  
}

void rbTransplant(pRBT *root,pRBT u,pRBT v)
{
	if(u->p==nil)
		(*root)=v;
	else if(u==u->p->left)
		u->p->left=v;
	else
		u->p->right=v;
	v->p=u->p;
}

pRBT treeMinimum(pRBT root)
{
	if(root==nil)
		return root;
	pRBT x=root;
	while(x->left!=nil)
	{
		x=x->left;
	}
	return x;
}

void rbDeleteFixup(pRBT *root,pRBT x)
{
	while(x != *root && x->color==BLACK)
	{
		if(x==x->p->left)
		{
			pRBT w=x->p->right;
			if(w->color==RED)
			{
				w->color=BLACK;
				x->p->color=RED;
				leftRotate(root,x->p);
				w=x->p->right;
			}
			if(w->left->color==BLACK && w->right->color==BLACK)
			{
				w->color=RED;
				x=x->p;
				if(x==*root)
					bh--;
			}
			else
			{
				if(w->right->color == BLACK)
				{
					w->left->color=BLACK;
					w->color=RED;
					rightRotate(root,w);
					w=x->p->right;
				}
				w->color=x->p->color;
				x->p->color=BLACK;
				w->right->color=BLACK;
				leftRotate(root,x->p);
				x=(*root);
			}
		}
		else
		{
			pRBT w=x->p->left;
			if(w->color==RED)
			{
				w->color=BLACK;
				x->p->color=RED;
				rightRotate(root,x->p);
				w=x->p->left;
			}
			if(w->left->color==BLACK && w->right->color==BLACK)
			{
				w->color=RED;
				x=x->p;
			}
			else
			{
				if(w->left->color == BLACK)
				{
					w->right->color=BLACK;
					w->color=RED;
					leftRotate(root,w);
					w=x->p->left;
				}
				w->color=x->p->color;
				x->p->color=BLACK;
				w->left->color=BLACK;
				rightRotate(root,x->p);
				x=(*root);
			}
		}
	}
	
	x->color=BLACK;
}

void rbDelete(pRBT *root,pRBT z)
{
	pRBT y=z,x;
	int yOrigColor=y->color;
	if(z->left==nil)
	{
		x=z->right;
		rbTransplant(root,z,x);
	}
	else if(z->right==nil)
	{
		x=z->left;
		rbTransplant(root,z,x);
	}
	else
	{
		y=treeMinimum(z->right);
		yOrigColor=y->color;
		x=y->right;
		if(y->p==z)
		{
			x->p=y;
		}
		else
		{
			rbTransplant(root,y,x);
			y->right=z->right;
			y->right->p=y;
		}
		rbTransplant(root,z,y);
		y->left=z->left;
		y->left->p=y;
		y->color=z->color;
		//从删除后替代节点向上直到根节点,修改新增域
		pRBT u=x;
		while(u!=nil)
		{
			updateGap(u);
			u=u->p;
		}
		if(yOrigColor==BLACK)
			rbDeleteFixup(root,x);
	}
}

void preTrav(pRBT root,char c)
{
	if(root==nil)
		return;
	else
	{
		printf("key:%d,gap:%d,min:%d,max:%d ",root->key,root->minGap,root->min,root->max);
		if(root->color==BLACK)
			printf("%s ","黑");
		else
			printf("%s ","红");
		printf("%c ",c);
		printf("\n");
		preTrav(root->left,'L');
		preTrav(root->right,'R');
	}
}

pRBT treeSearch(pRBT root,int key)
{
	pRBT x=root;
	while(x!=nil && x->key!=key)
	{
		if(key<x->key)
			x=x->left;
		else
			x=x->right;
	}
	return x;
}

void main()
{
	initNil();
	pRBT root=nil;
	rbInsert(&root,1);
	rbInsert(&root,5);
	rbInsert(&root,8);
	rbInsert(&root,10);
	rbInsert(&root,14);
	rbInsert(&root,17);
	preTrav(root,'M');
	printf("\n");
	printf("%d\n",root->minGap);
	pRBT z=treeSearch(root,10);
	rbDelete(&root,z);
	printf("%d\n",root->minGap);
	getchar();
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值