/**********************OST.h************************/
/*头文件*/
typedef struct node{
char color;
int key;
struct node * p;
struct node *left;
struct node * right;
int size;
} Node;
void left_rotate(Node ** root,Node * x);
void right_rotate(Node ** root,Node * x);
void RB_insert(Node * *root,Node * z);
void RB_insert_fixup(Node ** root,Node * z);
void Inorder_Tree_Walk(const Node * root);
void RB_transplant(Node **root,Node *u,Node *v);
Node * RB_minimum(Node * root);
void RB_delete(Node **root,Node *z);
void RB_delete_fixup(Node **root,Node *x);
Node * Tree_Search(Node *root,int k);
int os_rank(Node * root,Node *x);
Node * os_select(Node *x,int i);
/********************OST.c************************/
/*函数文件*/
#include "RBT.h"
#include <stdio.h>
extern Node sential;
void left_rotate(Node ** root,Node * x)
{ Node *y=x->right;
x->right=y->left;
if(y->left!=&sential)
y->left->p=x;
y->p=x->p;
if(x->p==&sential)
*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 right_rotate(Node **root,Node * x)
{ Node *y=x->left;
x->left=y->right;
if(y->right!=&sential)
y->right->p=x;
y->p=x->p;
if(x->p==&sential)
*root=y;
else if(x==x->p->right)
x->p->right=y;
else
x->p->left=y;
y->right=x;
x->p=y;
/*change the size of x and y */
y->size=x->size;
x->size=x->left->size+x->right->size+1;
}
void RB_insert(Node ** root,Node * z)
{ Node *x=*root;
Node *y=&sential;
while(x!=&sential)
{ y=x;
y->size+=1;
if(z->key<x->key)
x=x->left;
else
x=x->right;
}
if (y==&sential)
*root=z;
else if(z->key<y->key)
y->left=z;
else
y->right=z;
z->p=y;
z->color='r';
z->left=&sential;
z->right=&sential;
RB_insert_fixup(root,z);
}
void RB_insert_fixup(Node ** root,Node * z)
{ while(z->p->color=='r')
{ if(z->p==z->p->p->left)
{ Node *y=z->p->p->right;
if(y->color=='r')
{ y->color='b';
z->p->color='b';
z->p->p->color='r';
z=z->p->p;
}
else
{ if (z==z->p->right)
{ z=z->p;
left_rotate(root,z);
}
right_rotate(root,z->p->p);
z->p->color='b';
z->p->right->color='r';
}
}
else
{ Node *y=z->p->p->left;
if(y->color=='r')
{ y->color='b';
z->p->color='b';
z->p->p->color='r';
z=z->p->p;
}
else
{ if(z==z->p->left)
{ z=z->p;
right_rotate(root,z);
}
left_rotate(root,z->p->p);
z->p->color='b';
z->p->left->color='r';
}
}
}
(*root)->color='b';
}
void Inorder_Tree_Walk(const Node * root)
{ if( root!=&sential)
{
Inorder_Tree_Walk(root->left);
printf("key=%5d size=%5d\n",root->key,root->size);
Inorder_Tree_Walk(root->right);
}
}
void RB_transplant(Node **root,Node *u,Node *v)
{ if(u->p==&sential)
*root=v;
else if(u->p->left==u)
u->p->left=v;
else
u->p->right=v;
v->p=u->p;
}
Node * RB_minimum(Node * root)
{ while(root->left!=&sential)
root=root->left;
return root;
}
void RB_delete(Node **root,Node *z)
{ Node *y=z;
Node *x;
Node *y_original_place;
char y_o_c=y->color;
if(z->left==&sential)
{ RB_transplant(root,z,z->right);
x=z->right;
}
else if(z->right==&sential)
{ RB_transplant(root,z,z->left);
x=z->left;
}
else
{ y=RB_minimum(z->right);
y_o_c=y->color;
x=y->right;
if(y->p==z)
x->p=y;
else
{ RB_transplant(root,y,x);
y->right=z->right;
y->right->p=y;
}
RB_transplant(root,z,y);
y->left=z->left;
//be careful!!
y->size=z->size;
y->left->p=y;
y->color=z->color;
}
y_original_place=x;
//decrement the node'size from y's original position to the root
while(y_original_place->p!=&sential)
{ y_original_place->p->size-=1;
y_original_place=y_original_place->p;
}
if(y_o_c=='b')
RB_delete_fixup(root,x);
}
void RB_delete_fixup(Node **root,Node *x)
{ Node *w;
while(x->color=='b'&&x!=*root)
{ if(x==x->p->left)
{ w=x->p->right;
if(w->color=='r')
{ w->color='b';
x->p->color='r';
right_rotate(root,w);
w=x->p->right;
}
if(w->color=='b')
{ w->color='r';
x=x->p;
}
else
{ if(w->right->color=='b')
{ w->left->color='b';
w->color='r';
right_rotate(root,w);
w=x->p->right;
}
w->color=w->p->color;
w->p->color='b';
w->right->color='b';
left_rotate(root,w->p);
x=*root;
}
}
else
{ w=x->p->left;
if(w->color=='r')
{ w->color='b';
x->p->color='r';
left_rotate(root,w);
w=x->p->left;
}
if(w->color=='b')
{ w->color='r';
x=x->p;
}
else
{ if(w->left->color=='b')
{ w->right->color='b';
w->color='r';
left_rotate(root,w);
w=x->p->left;
}
w->color=w->p->color;
w->p->color='b';
w->left->color='b';
right_rotate(root,w->p);
x=*root;
}
}
}
}
//how can i solve the search(do not have the key) ??
Node * Tree_Search(Node *root,int k)
{ if (root==&sential||k==root->key)
return root;
if (k<root->key)
return Tree_Search(root->left,k);
else
return Tree_Search(root->right,k);
}
Node * os_select(Node *x,int i)
{ int r=x->left->size+1;
if(r==i)
return x;
else if(r<i)
return os_select(x->right,i-r);
else
return os_select(x->left,i);
}
int os_rank(Node * root,Node *x)
{ int r=x->left->size+1;
Node *y=x;
while(y!=root)
{ if(y==y->p->right)
r+=y->p->left->size+1;
y=y->p;
}
return r;
}
/************************drive_OST.c*******************************/
/* 测试插入与删除中各节点size性质的维护*/
#include "RBT.h"
#include <stdio.h>
#include <stdlib.h>
Node sential={.color='b',.size=0};//sential's size is 0
int main(void)
{ Node * RBT_root=&sential;
int key;
printf("Please enter the key to insert(q to quit)\n");
while(scanf("%d",&key)==1)
{
Node *p_node=malloc(sizeof(Node));
p_node->key=key;
p_node->size=1;
RB_insert(&RBT_root,p_node);
}
printf("Sorting\n");
Inorder_Tree_Walk(RBT_root);
putchar('\n');
printf("please enter the key you want delete\n");
while(getchar()!='\n')
continue;
int k;
while(scanf("%d",&k)==1)
{ Node * res=Tree_Search(RBT_root,k);
if(res==NULL)
printf("%d is not in the BST\n",k);
RB_delete(&RBT_root,res);
}
printf("Now the RBT(after sorting)\n");
Inorder_Tree_Walk(RBT_root);
putchar('\n');
for(int i=0;i<5;i++)
printf(" %dth smallest =%d \n",i+1,
os_select(RBT_root,i+1)->key);
}