struct tree_node* _insert_rebalance(struct tree_node* node, struct tree_node* root) { struct tree_node *parent, *gparent, *uncle, *tmp; while ((parent = node->parent_node) && parent->color == Red) { gparent = parent->parent_node; if (parent == gparent->left_node) { uncle = gparent->right_node; if (uncle && uncle->color == Red) { uncle->color = Black; parent->color = Black; gparent->color = Red; node = gparent; } else { if (parent->right_node == node) { root = _rotate_left(parent, root); tmp = parent; parent = node; node = tmp; } parent->color = Black; gparent->color = Red; root = _rotate_right(gparent, root); } } else { uncle = gparent->left_node; if (uncle && uncle->color == Red) { uncle->color = Black; parent->color = Black; gparent->color = Red; node = gparent; } else { if (parent->left_node == node) { root = _rotate_right(parent, root); tmp = parent; parent = node; node = tmp; } parent->color = Black; gparent->color = Red; root = _rotate_left(gparent, root); } } } root->color = Black; return root; }
/*! Rebalance the tree after insertion of a node. */ void GsTreeBase::_rebalance ( GsTreeNode *x ) { GS_TRACE1("Rebalance"); GsTreeNode *y; while ( x!=_root && RED(x->parent) ) { // if ( !x->parent->parent ) REPORT_ERROR if ( x->parent==x->parent->parent->left ) { y = x->parent->parent->right; if ( RED(y) ) { // handle case 1 (see CLR book, pp. 269) x->parent->color = GsTreeNode::Black; y->color = GsTreeNode::Black; x->parent->parent->color = GsTreeNode::Red; x = x->parent->parent; } else { if ( x==x->parent->right ) { // transform case 2 into case 3 (see CLR book, pp. 269) x = x->parent; _rotate_left ( x ); } // handle case 3 (see CLR book, pp. 269) x->parent->color = GsTreeNode::Black; x->parent->parent->color = GsTreeNode::Red; _rotate_right ( x->parent->parent ); } } else { y = x->parent->parent->left; if ( RED(y) ) { // handle case 1 (see CLR book, pp. 269) x->parent->color = GsTreeNode::Black; y->color = GsTreeNode::Black; x->parent->parent->color = GsTreeNode::Red; x = x->parent->parent; } else { if ( x==x->parent->left ) { // transform case 2 into case 3 (see CLR book, pp. 269) x = x->parent; _rotate_right ( x ); } // handle case 3 (see CLR book, pp. 269) x->parent->color = GsTreeNode::Black; x->parent->parent->color = GsTreeNode::Red; _rotate_left ( x->parent->parent ); } } } }
/*! Method for restoring red-black properties after deletion. */ void GsTreeBase::_fix_remove ( GsTreeNode *x ) { GS_TRACE1("Fix Remove"); while ( x!=_root && BLACK(x) ) { if ( x==x->parent->left ) { GsTreeNode *w = x->parent->right; if ( RED(w) ) { w->color = GsTreeNode::Black; x->parent->color = GsTreeNode::Red; _rotate_left ( x->parent ); w = x->parent->right; } if ( BLACK(w->left) && BLACK(w->right) ) { w->color = GsTreeNode::Red; x = x->parent; } else { if ( BLACK(w->right) ) { w->left->color = GsTreeNode::Black; w->color = GsTreeNode::Red; _rotate_right ( w ); w = x->parent->right; } w->color = x->parent->color; x->parent->color = GsTreeNode::Black; w->right->color = GsTreeNode::Black; _rotate_left ( x->parent ); x = _root; } } else { GsTreeNode *w = x->parent->left; if ( RED(w) ) { w->color = GsTreeNode::Black; x->parent->color = GsTreeNode::Red; _rotate_right ( x->parent ); w = x->parent->left; } if ( BLACK(w->left) && BLACK(w->right) ) { w->color = GsTreeNode::Red; x = x->parent; } else { if ( BLACK(w->left) ) { w->right->color = GsTreeNode::Black; w->color = GsTreeNode::Red; _rotate_left ( w ); w = x->parent->left; } w->color = x->parent->color; x->parent->color = GsTreeNode::Black; w->left->color = GsTreeNode::Black; _rotate_right ( x->parent ); x = _root; } } } x->color = GsTreeNode::Black; }
struct tree_node* _remove_rebalance(struct tree_node *node, struct tree_node *parent, struct tree_node *root) { struct tree_node *other, *o_left, *o_right; while ((!node || node->color == Black) && node != root) { if (parent->left_node == node) { other = parent->right_node; if (other->color == Red) { other->color = Black; parent->color = Red; root = _rotate_left(parent, root); other = parent->right_node; } if ((!other->left_node || other->left_node->color == Black) && (!other->right_node || other->right_node->color == Black)) { other->color = Red; node = parent; parent = node->parent_node; } else { if (!other->right_node || other->right_node->color == Black) { if ((o_left = other->left_node)) { o_left->color = Black; } other->color = Red; root = _rotate_right(other, root); other = parent->right_node; } other->color = parent->color; parent->color = Black; if (other->right_node) { other->right_node->color = Black; } root = _rotate_left(parent, root); node = root; break; } } else { other = parent->left_node; if (other->color == Red) { other->color = Black; parent->color = Red; root = _rotate_right(parent, root); other = parent->left_node; } if ((!other->left_node || other->left_node->color == Black) && (!other->right_node || other->right_node->color == Black)) { other->color = Red; node = parent; parent = node->parent_node; } else { if (!other->left_node || other->left_node->color == Black) { if ((o_right = other->right_node)) { o_right->color = Black; } other->color = Red; root = _rotate_left(other, root); other = parent->left_node; } other->color = parent->color; parent->color = Black; if (other->left_node) { other->left_node->color = Black; } root = _rotate_right(parent, root); node = root; break; } } } if (node) { node->color = Black; } return root; }