static void __rb_remove_fixup( struct clib_rb* pTree, struct clib_rb_node* x ) { while (x != pTree->root && x->color == clib_black) { if (x == x->parent->left) { struct clib_rb_node* w = x->parent->right; if (w->color == clib_red) { w->color = clib_black; x->parent->color = clib_red; __left_rotate (pTree, x->parent); w = x->parent->right; } if (w->left->color == clib_black && w->right->color == clib_black) { w->color = clib_red; x = x->parent; } else { if (w->right->color == clib_black) { w->left->color = clib_black; w->color = clib_red; __right_rotate (pTree, w); w = x->parent->right; } w->color = x->parent->color; x->parent->color = clib_black; w->right->color = clib_black; __left_rotate (pTree, x->parent); x = pTree->root; } } else { struct clib_rb_node* w = x->parent->left; if (w->color == clib_red) { w->color = clib_black; x->parent->color = clib_red; __right_rotate (pTree, x->parent); w = x->parent->left; } if (w->right->color == clib_black && w->left->color == clib_black) { w->color = clib_red; x = x->parent; } else { if (w->left->color == clib_black) { w->right->color = clib_black; w->color = clib_red; __left_rotate (pTree, w); w = x->parent->left; } w->color = x->parent->color; x->parent->color = clib_black; w->left->color = clib_black; __right_rotate (pTree, x->parent); x = pTree->root; } } } x->color = clib_black; }
void __rb_insert_fixup(rb_tree_node* node) { // red parent. for (; node->parent->color == red;) { // node's parent is left child. if (__is_left_child(node->parent)) { // node->parent->color == red ==> node->parent != root_ ==> // node->parent->parent != nil. // red uncle. rb_tree_node* uncle = __grandparent(node)->r_child; if (uncle->color == red) { uncle->color = node->parent->color = black; __grandparent(node)->color = red; node = __grandparent(node); } else { // make sure node to be left child. if (__is_right_child(node)) { node = node->parent; __left_rotate(node); } // fall through. // black height of left subtree rooted by node->parent->parent. node->parent->color = black; __grandparent(node)->color = red; // right rotate to adjust black height. __right_rotate(__grandparent(node)); // exit loop here. cos' node's parent is black(Line: 167). } } // node's parent is right child. else { rb_tree_node* uncle = __grandparent(node)->l_child; if (uncle->color == red) { uncle->color = node->parent->color = black; __grandparent(node)->color = red; node = __grandparent(node); } else { // make sure node to be right child. if (__is_left_child(node)) { node = node->parent; __right_rotate(node); } node->parent->color = black; __grandparent(node)->color = red; __left_rotate(__grandparent(node)); } } } root_->color = black; }
static __inline void __rebalance_for_add(rbtree_head* __x, rbtree_head** __root) { assert(__x && __root); __x->color = RB_RED; while (__x != *__root && __x->parent->color == RB_RED) { if (__x->parent == __x->parent->parent->left) { rbtree_head* __y = __x->parent->parent->right; if (__y && __y->color == RB_RED) { __x->parent->color = RB_BLACK; __y->color = RB_BLACK; __x->parent->parent->color = RB_RED; __x = __x->parent->parent; } else { if (__x == __x->parent->right) { __x = __x->parent; __left_rotate(__x, __root); } __x->parent->color = RB_BLACK; __x->parent->parent->color = RB_RED; __right_rotate(__x->parent->parent, __root); } } else { rbtree_head* __y = __x->parent->parent->left; if (__y && __y->color == RB_RED) { __x->parent->color = RB_BLACK; __y->color = RB_BLACK; __x->parent->parent->color = RB_RED; __x = __x->parent->parent; } else { if (__x == __x->parent->left) { __x = __x->parent; __right_rotate(__x, __root); } __x->parent->color = RB_BLACK; __x->parent->parent->color = RB_RED; __left_rotate(__x->parent->parent, __root); } } } (*__root)->color = RB_BLACK; }
static void __rb_insert_fixup( struct clib_rb* pTree, struct clib_rb_node* x ) { while (x != pTree->root && x->parent->color == clib_red) { if (x->parent == x->parent->parent->left) { struct clib_rb_node* y = x->parent->parent->right; if (y->color == clib_red) { x->parent->color = clib_black; y->color = clib_black; x->parent->parent->color = clib_red; x = x->parent->parent; } else { if (x == x->parent->right){ x = x->parent; __left_rotate (pTree, x); } x->parent->color = clib_black; x->parent->parent->color = clib_red; __right_rotate (pTree, x->parent->parent); } } else { struct clib_rb_node* y = x->parent->parent->left; if (y->color == clib_red) { x->parent->color = clib_black; y->color = clib_black; x->parent->parent->color = clib_red; x = x->parent->parent; } else { if (x == x->parent->left) { x = x->parent; __right_rotate (pTree, x); } x->parent->color = clib_black; x->parent->parent->color = clib_red; __left_rotate (pTree, x->parent->parent); } } } pTree->root->color = clib_black; }
void __rb_erase_fixup(rb_tree_node* node) { for (; node != root_ && node->color == black;) { // node is left child. if (__is_left_child(node)) { // sibling != null, due to the black-height rule. rb_tree_node* sibling = node->parent->r_child; if (sibling->color == red) { // node->parent->color = black. // exchange sibling's color with node's parent's color. sibling->color = black; node->parent->color = red; __left_rotate(node->parent); sibling = node->parent->r_child; } // fall through. // black sibling with two black children. if (sibling->l_child->color == black && sibling->r_child->color == black) { // decrease black height. sibling->color = red; // subtree rooted by node is legal. node = node->parent; } // black sibling with one black child at most. else { // left child is red. if (sibling->r_child->color == black) { sibling->color = red; sibling->l_child->color = black; __right_rotate(sibling); sibling = node->parent->r_child; } // fall through. // right child is red. sibling->color = sibling->parent->color; sibling->parent->color = black; sibling->r_child->color = black; __left_rotate(node->parent); // exit from for loop. node = root_; } } // node is right child. else { rb_tree_node* sibling = node->parent->l_child; if (sibling->color == red) { sibling->color = black; node->parent->color = red; __right_rotate(node->parent); sibling = node->parent->l_child; } if (sibling->l_child->color == black && sibling->r_child->color == black) { sibling->color = red; node = node->parent; } else { if (sibling->l_child->color == black) { sibling->color = red; sibling->r_child->color = black; __left_rotate(sibling); sibling = node->parent->l_child; } sibling->color = sibling->parent->color; sibling->parent->color = black; sibling->l_child->color = black; __right_rotate(node->parent); node = root_; } } } node->color = black; }
static void avl_fixup_insert(struct avl_root *r, struct avl_node *x) { struct avl_node *parent; struct avl_node *child; for(; (parent = x->p); x = parent){ if (parent->l == x) { parent->balance++; if (parent->balance == 0) break; if (parent->balance == 1) continue; //rotate //parent ->balance is 2 //assert(parent->balance == 2); if (x->balance == 1) { //LL x->balance = 0; parent->balance = 0; __right_rotate(parent, r); break; } //LR, x->balance == -1 child = x->r; /* switch (child->balance) { case 1: child->balance = x->balance = 0; parent->balance = -1; break; case -1: child->balance = parent->balance = 0; x->balance = 1; break; case 0: x->balance = parent->balance = 0; break; } */ parent->balance = x->balance = 0; if (child->balance == 1) parent->balance = -1; else if (child->balance == -1) x->balance = 1; child->balance = 0; avl_lr_rotate(parent, r); break; } else { parent->balance--; if (parent->balance == 0) break; if (parent->balance == -1) continue; //rotate //assert(parent->balance == -2); if (x->balance == -1) { x->balance = parent->balance = 0; __left_rotate(parent, r); break; } //RL, x->balance = 1 child = x->l; /* switch (child->balance) { case -1: child->balance = x->balance = 0; parent->balance = 1; break; case 1: child->balance = parent->balance = 0; x->balance = -1; break; case 0: x->balance = parent->balance = 0; break; } */ parent->balance = x->balance = 0; if (child->balance == -1) parent->balance = 1; else if (child->balance == 1) x->balance = -1; child->balance = 0; avl_rl_rotate(parent, r); break; } } }
static inline void avl_rl_rotate(struct avl_node *parent, struct avl_root *r) { __right_rotate(parent->r, r); __left_rotate(parent, r); }
// x's balance is to be decreased // left == true child is left, left == false, child is right static void avl_fixup_del(struct avl_root *r, struct avl_node *x, bool left) { struct avl_node *parent; struct avl_node *child; struct avl_node *gc; for(;x;x=parent){ parent = x->p; if (left) { x->balance--; if (x->balance == -1) break; if (parent && parent->r == x) left = false; if (x->balance == 0) continue; // x's balance is -1, now to be -2, so should rotate. child = x->r; //assert(x->balance == -2 && child); if (child->balance == 0) { x->balance = -1; child->balance = 1; __left_rotate(x, r); break; } if (child->balance == -1) { x->balance = child->balance = 0; __left_rotate(x, r); continue; } gc = child->l; //child 's balance == 1 //assert(child->balance == 1 && gc); x->balance = child->balance = 0; if(gc->balance == -1) x->balance = 1; else if(gc->balance == 1) child->balance = -1; gc->balance = 0; avl_rl_rotate(x, r); } else { x->balance++; if (x->balance == 1) break; if (parent && parent->l == x) left = true; if (x->balance == 0) continue; child = x->l; //assert(x->balance == 2 && child); if (child->balance == 0) { x->balance = 1; child->balance = -1; __right_rotate(x, r); break; } if (child->balance == 1) { x->balance = child->balance = 0; __right_rotate(x, r); continue; } gc = child->r; //assert(child->balance == -1 && gc); x->balance = child->balance = 0; if(gc->balance == 1) x->balance = -1; else if(gc->balance == -1) child->balance = 1; gc->balance = 0; avl_lr_rotate(x, r); } } }
static __inline rbtree_head* __rebalance_for_del(rbtree_head* __z, rbtree_head** __root) { rbtree_head* __y = __z; rbtree_head* __x = 0; rbtree_head* __x_parent = 0; assert(__z && __root); if (__y->left == 0) /* __z has at most one non-null child. y == z. */ __x = __y->right; /* __x might be null.*/ else if (__y->right == 0) /* __z has exactly one non-null child. y == z. */ __x = __y->left; /* __x is not null.*/ else { /* __z has two non-null children. Set __y to */ __y = __y->right; /* __z's successor. __x might be null. */ while (__y->left != 0) __y = __y->left; __x = __y->right; } if (__y != __z) { /* relink y in place of z. y is z's successor */ __z->left->parent = __y; __y->left = __z->left; if (__y != __z->right) { __x_parent = __y->parent; if (__x) __x->parent = __y->parent; __y->parent->left = __x; /* __y must be a child of left */ __y->right = __z->right; __z->right->parent = __y; } else __x_parent = __y; if (*__root == __z) *__root = __y; else if (__z->parent->left == __z) __z->parent->left = __y; else __z->parent->right = __y; __y->parent = __z->parent; __swap(__y->color, __z->color); __y = __z; /* __y now points to node to be actually deleted */ } else { /* __y == __z */ __x_parent = __y->parent; if (__x) __x->parent = __y->parent; if (*__root == __z) *__root = __x; else if (__z->parent->left == __z) __z->parent->left = __x; else __z->parent->right = __x; } if (__y->color != RB_RED) { while (__x != *__root && (__x == 0 || __x->color == RB_BLACK)) if (__x == __x_parent->left) { rbtree_head* __w = __x_parent->right; if (__w->color == RB_RED) { __w->color = RB_BLACK; __x_parent->color = RB_RED; __left_rotate(__x_parent, __root); __w = __x_parent->right; } if ((__w->left == 0 || __w->left->color == RB_BLACK) && (__w->right == 0 || __w->right->color == RB_BLACK)) { __w->color = RB_RED; __x = __x_parent; __x_parent = __x_parent->parent; } else { if (__w->right == 0 || __w->right->color == RB_BLACK) { if (__w->left) __w->left->color = RB_BLACK; __w->color = RB_RED; __right_rotate(__w, __root); __w = __x_parent->right; } __w->color = __x_parent->color; __x_parent->color = RB_BLACK; if (__w->right) __w->right->color = RB_BLACK; __left_rotate(__x_parent, __root); break; } } else { /* same as above, with right <-> left. */ rbtree_head* __w = __x_parent->left; if (__w->color == RB_RED) { __w->color = RB_BLACK; __x_parent->color = RB_RED; __right_rotate(__x_parent, __root); __w = __x_parent->left; } if ((__w->right == 0 || __w->right->color == RB_BLACK) && (__w->left == 0 || __w->left->color == RB_BLACK)) { __w->color = RB_RED; __x = __x_parent; __x_parent = __x_parent->parent; } else { if (__w->left == 0 || __w->left->color == RB_BLACK) { if (__w->right) __w->right->color = RB_BLACK; __w->color = RB_RED; __left_rotate(__w, __root); __w = __x_parent->left; } __w->color = __x_parent->color; __x_parent->color = RB_BLACK; if (__w->left) __w->left->color = RB_BLACK; __right_rotate(__x_parent, __root); break; } } if (__x) __x->color = RB_BLACK; } return __y; }