算法导论 红黑树的扩张 动态顺序统计

#include     
#include     
#define RED 1    
#define BLACK 0    
    
typedef struct RBTreeNode    
{    
    int key;    
    int color; 
	int size;
    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->size=0;
}    
    
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;   
	//维护子树数目
	y->size=x->size;
	x->size=x->left->size+x->right->size+1;
}    
    
void rightRotate(pRBT *root,pRBT x)    
{    
    //右旋要有左子树    
    if(x->left==nil)    
        return;    
    pRBT y=x->left;    
    x->left=y->right;
	if(y->right != nil)    
        y->right->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->right=x;    
    x->p=y;   
	//维护子树数目
	x->size=y->size;
	y->size=y->left->size+y->right->size+1;
}    
    
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;
	z->size=1;
    pRBT x=(*root);    
    pRBT y=nil;    
    while(x != nil)    
    {    
		x->size++;//从根下降过程中,增加路径上所有子树数目
        y=x;    
        if(z->keykey)    
        {    
            x=x->left; 			
        }    
        else    
        {    
            x=x->right;    
        }  	
    }    
    z->p=y;    
    if(y==nil)    
    {    
        (*root)=z;    
    }    
    else if(z->keykey)    
    {    
        y->left=z;    
    }    
    else    
    {    
        y->right=z;    
    }    
    z->left=nil;    
    z->right=nil;    
    z->color=RED;    
    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->p,x;
	//新增一段回溯到根的迭代,减少路径上每个结点的子树数目
	while(y)
	{
		y->size--;
		y=y->p;
	}
    y=z;  
    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;  
        if(yOrigColor==BLACK)  
            rbDeleteFixup(root,x);  
    }  
}  
  
void preTrav(pRBT root,char c)  
{  
    if(root==nil)  
        return;  
    else  
    {  
        printf("%d ",root->key);  
        if(root->color==BLACK)  
            printf("%s ","黑");  
        else  
            printf("%s ","红");  
        printf("%c ",c);  
        preTrav(root->left,'L');  
        preTrav(root->right,'R');  
    }  
}  
  
pRBT treeSearch(pRBT root,int key)  
{  
    pRBT x=root;  
    while(x!=nil && x->key!=key)  
    {  
        if(keykey)  
            x=x->left;  
        else  
            x=x->right;  
    }  
    return x;  
}  

pRBT at(pRBT root,int i)
{
	if(root==nil)
		return nil;
	pRBT x=root;
	int r=x->left->size+1;
	if(i==r)
		return x;
	else if(ileft,i);
	else
		return at(x->right,i-r);
}

int getIndex(pRBT root,pRBT x)
{
	int r=x->left->size+1;
	pRBT y=x;
	while(y != root)
	{
		if(y==y->p->right)
			r=r+y->p->left->size+1;
		y=y->p;
	}
	return r;
}
  
void main()  
{  
    initNil();  
    pRBT root=nil;  
    rbInsert(&root,100);  
    rbInsert(&root,80);  
    rbInsert(&root,90);  
    rbInsert(&root,70);  
    rbInsert(&root,10);  
    rbInsert(&root,20);  
    rbInsert(&root,30);  
    rbInsert(&root,50);  
    rbInsert(&root,60);  
    rbInsert(&root,40);  
    
	pRBT x=at(root,3);
	printf("%d\n",x->key);

	int r=getIndex(root,x);
	printf("%d\n",r);
    getchar();  
} 

你可能感兴趣的:(算法导论)