Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
/*! 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 );
          }
       }
    }
 }
Exemplo n.º 3
0
/*! 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;
 }
Exemplo n.º 4
0
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;
}