/*******************************************
Module: redblacktree.c
Notices: Copyrigjt (c) 2007-2010 ls
*******************************************/
#include "redblacktree.h"
static void rbt_rotate_left(rb_tree_t *t,rb_node_t *x)
{
rb_node_t *y=x->right;
x->right=y->left;
if(y->left!=t->nil){
y->left->parent=x;
}
y->parent=x->parent;
if(x->parent!=t->nil){
if(x==x->parent->left){
x->parent->left=y;
}
else{
x->parent->right=y;
}
}
else{
t->root=y;
}
y->left=x;
x->parent=y;
}
static void rbt_rotate_right(rb_tree_t *t,rb_node_t *x)
{
rb_node_t *y=x->left;
x->left=y->right;
if(y->right!=t->nil){
y->right->parent=x;
}
y->parent=x->parent;
if(x->parent!=t->nil){
if(x==x->parent->right){
x->parent->right=y;
}
else{
x->parent->left=y;
}
}
else{
t->root=y;
}
}
static void rbt_insert_fixup(rb_tree_t *t,rb_node_t *z)
{
rb_node_t *y;
/* check red-black properties */
while((z!=t->root)&&RBT_IS_RED(z->parent)){
/* have a violation */
if(z->parent==z->parent->parent->left){
y=z->parent->parent->right;
if(RBT_IS_RED(y)){
/* uncle is RED */
RBT_BLACK(z->parent);
RBT_BLACK(y);
RBT_RED(z->parent->parent);
z=z->parent->parent;
}
else{
/* uncle is BLACK */
if(z==z->parent->right){
/* make z a left child */
z=z->parent;
rbt_rotate_left(t,z);
}
/* recolor and rotate */
RBT_BLACK(z->parent);
RBT_RED(z->parent->parent);
rbt_rotate_right(t,z->parent->parent);
}
}
else{
/* mirror image of above code */
y=z->parent->parent->left;
if(RBT_IS_RED(y)){
/* uncle is RED */
RBT_BLACK(z->parent);
RBT_BLACK(y);
RBT_RED(z->parent->parent);
z=z->parent->parent;
}
else{
/* uncle is BLACK */
if(z==z->parent->left){
z=z->parent;
rbt_rotate_right(t,z);
}
RBT_BLACK(z->parent);
RBT_RED(z->parent->parent);
rbt_rotate_left(t,z->parent->parent);
}
}
}
RBT_BLACK(t->root);
}
static void rbt_delete_fixup(rb_tree_t *t,rb_node_t *x)
{
rb_node_t *w;
while((x!=t->root)&&RBT_IS_BLACK(x)){
if(x==x->parent->left){
w=x->parent->right;
if(RBT_IS_RED(w)){
RBT_BLACK(w);
RBT_RED(x->parent);
rbt_rotate_left(t,x->parent);
w=x->parent->right;
}
if(RBT_IS_BLACK(w->left)&&(RBT_IS_BLACK(w->right))){
RBT_RED(w);
x=x->parent;
}
else{
if(RBT_IS_BLACK(w->right)){
RBT_BLACK(w->left);
RBT_RED(w);
rbt_rotate_right(t,w);
w=x->parent->right;
}
RBT_COPY_COLOR(w,x->parent);//w->color=x->parent->color;
RBT_BLACK(x->parent);
RBT_BLACK(w->right);
rbt_rotate_left(t,x->parent);
x=t->root;
}
}
else{
/* clause with 'right' and left exchanged */
w=x->parent->left;
if(RBT_IS_RED(w)){
RBT_BLACK(w);
RBT_RED(x->parent);
rbt_rotate_right(t,x->parent);
w=x->parent->left;
}
if((RBT_IS_BLACK(w->right))&&(RBT_IS_BLACK(w->left))){
RBT_RED(w);
x=x->parent;
}
else{
if(RBT_IS_BLACK(w->left)){
RBT_BLACK(w->right);
RBT_RED(w);
rbt_rotate_left(t,w);
w=x->parent->left;
}
RBT_COPY_COLOR(w,x->parent);//w->color=x->parent->color;
RBT_BLACK(x->parent);
RBT_BLACK(w->left);
rbt_rotate_right(t,x->parent);
x=t->root;
}
}
}
RBT_BLACK(x);
}
static void rbt_in_order_internal(rb_tree_t *t,rb_node_t *n,void (*RbtOrderCallBack)(rb_node_t *))
{
if(n==t->nil){
return;
}
rbt_in_order_internal(t,n->left,RbtOrderCallBack);
RbtOrderCallBack(n);
rbt_in_order_internal(t,n->right,RbtOrderCallBack);
}
void rbt_init(rb_tree_t *tree,rb_node_t *nil)
{
RBT_NIL_INIT(nil);
tree->nil=nil;
tree->root=nil;
}
int rbt_insert(rb_tree_t *t,rb_node_t *z)
{
rb_node_t *y,*x;
y=t->nil;
x=t->root;
while(x!=t->nil){
if(EQ(z->key,x->key)){
return(1);
}
y=x;
x=LT(z->key,x->key)?x->left:x->right;
}
z->parent=y;
if(y!=t->nil){
if(LT(z->key,y->key)){
y->left=z;
}
else{
y->right=z;
}
}
else{
t->root=z;
}
z->left=t->nil;
z->right=t->nil;
RBT_RED(z);
rbt_insert_fixup(t,z);
return(0);
}
rb_node_t *rbt_delete(rb_tree_t *t,rb_node_t *z)
{
rb_node_t *x,*y;
if((z->left==t->nil)||(z->right==t->nil)){
y=z; /* y has a nil node as a child */
}
else{
y=z->right; /* find tree successor with a nil node as a child */
while(y->left!=t->nil){
y=y->left;
}
}
/* x is y's only child */
if(y->left!=t->nil){
x=y->left;
}
else{
x=y->right;
}
/* delete y from parent chain */
x->parent=y->parent;
if(y->parent!=t->nil){
if(y==y->parent->left){
y->parent->left=x;
}
else{
y->parent->right=x;
}
}
else{
t->root=x;
}
if(y!=z){
z->key=y->key;
z->val=y->val;
}
if(RBT_IS_BLACK(y)){
rbt_delete_fixup(t,x);
}
return(y);
}
rb_node_t *rbt_find(rb_tree_t *t,int key)
{
rb_node_t *y=t->root;
while(y!=t->nil){
if(EQ(key,y->key)){
return(y);
}
else{
y=LT(key,y->key)?y->left:y->right;
}
}
return(NULL);
}
void rbt_in_order(rb_tree_t *t,void (*RbtOrderCallBack)(rb_node_t *))
{
if(t->root==t->nil){
return;
}
rbt_in_order_internal(t,t->root,RbtOrderCallBack);
}
rb_node_t *rbt_min(rb_tree_t *t)
{
rb_node_t *node=t->root;
while (node->left != t->nil) {
node = node->left;
}
return node;
}
rb_node_t *rbt_max(rb_tree_t *t)
{
rb_node_t *node=t->root;
while (node->right != t->nil) {
node = node->right;
}
return node;
}
|