/******************************************* 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; }
|