Exemplo n.º 1
0
BSTNode* CC RebalanceLeft ( BSTNode *y, BSTNode *x )
{
    /* detect child balance */
    if ( LEFT_HEAVY ( x ) )
        return RotateRightAtY ( y, x );

    /* child is right heavy */
    return RotateLeftAtXRightAtY ( y, x );
}
Exemplo n.º 2
0
/**
 * // node, current node to balance
 * // root, the root node of the tree
 * 
 * RETURNS the new child for the parent
 */
static void avl_balance_node(struct avl_node **parent) 
{
    assert(parent != NULL);
    struct avl_node *node = *parent;

    // get balance for node
    short lh = (node->left != NULL) ? node->left->height : 0;
    short rh = (node->right != NULL) ? node->right->height : 0;
    short balance = lh - rh;

    //printf("balance %d\n", balance);
    if (balance == -1) 
    {
        // handle right subtree too high
        assert(node->right != NULL);
        if((node->right->right != NULL) && 
                (node->right->left != NULL) && 
                LEFT_HEAVY(node->right)) 
        {
            avl_rotate_right(&(node->right));
        }
        avl_rotate_left(parent);
        //printf("rotation done\n");
    } 
    else if (balance == 1) 
    {
        // handle left subtree too high
        // check for left right case
        assert(node->left != NULL);
        if((node->left->left != NULL) && 
                (node->left->right != NULL) && 
                RIGHT_HEAVY(node->left)) 
        {
            avl_rotate_left(&(node->left));
        }
        avl_rotate_right(parent);
        //printf("rotation done\n");
    } 
    else {
        ;
    }
    assert(parent != NULL);
    assert(*parent != NULL);
}
Exemplo n.º 3
0
static
void CC RebalanceAfterInsert ( BSTNode **root, BSTNode *y, BSTNode *x )
{
    BSTNode *w, *z;

    /* detect left insertion */
    if ( y -> child [ 0 ] == x )
    {
        /* if y was right-heavy, done */
        if ( RIGHT_HEAVY ( y ) )
        {
            CLR_BALANCE ( y, RIGHT );
            return;
        }

        /* rebalance left insertion */
        w = RebalanceLeft ( y, x );
    }

    /* right insertion */
    else
    {
        /* if y was left-heavy, done */
        if ( LEFT_HEAVY ( y ) )
        {
            CLR_BALANCE ( y, LEFT );
            return;
        }

        /* rebalance right insertion */
        w = RebalanceRight ( y, x );
    }

    /* fix parent to child */
    assert ( BALANCE ( w ) == 0 );
    z = w -> par;
    if ( z == 0 )
        * root = w;
    else
        z -> child [ z -> child [ 1 ] == y ] = w;
}
Exemplo n.º 4
0
/* BSTreeUnlink
 *  removes a node from tree
 */
static
void CC RebalanceAfterUnlink ( BSTNode **root, BSTNode *q, int dir )
{
    while ( q != 0 )
    {
        BSTNode *w, *x, *y = q;
        q = PARENT ( q );

        if ( ! dir )
        {
            if ( q && q -> child [ 1 ] == y )
                dir = 1;

            /* simulate an increment of balance */
            switch ( BALANCE ( y ) )
            {
            case 0:
                SET_BALANCE ( y, RIGHT );
                return;
            case LEFT:
                CLR_BALANCE ( y, LEFT );
                break;
            case RIGHT:
                /* y has just become ++ */
                x = y -> child [ 1 ];
                if ( LEFT_HEAVY ( x ) )
                {
                    w = RotateRightAtXLeftAtY ( y, x );
                    if ( q == 0 )
                        * root = w;
                    else
                        q -> child [ dir ] = w;
                }
                else
                {
                    w = y -> child [ 1 ] = x -> child [ 0 ];
                    x -> child [ 0 ] = y;
                    SET_PARENT ( x, q );
                    SET_PARENT ( y, x );
                    if ( w != 0 )
                        SET_PARENT ( w, y );
                    if ( q == 0 )
                        * root = x;
                    else
                        q -> child [ dir ] = x;
                    if ( BALANCE ( x ) == 0 )
                    {
                        SET_BALANCE ( x, LEFT );
                        SET_PARBAL ( y, x, RIGHT );
                        return;
                    }
                    ZERO_BALANCE ( x );
                    ZERO_BALANCE ( y );
                    /* y = x; */
                }
                break;
            }
        }

        /* symmetric case */
        else
        {
            if ( q && q -> child [ 0 ] == y )
                dir = 0;

            switch ( BALANCE ( y ) )
            {
            case 0:
                SET_BALANCE ( y, LEFT );
                return;
            case LEFT:
                /* y has just become -- */
                x = y -> child [ 0 ];
                if ( RIGHT_HEAVY ( x ) )
                {
                    w = RotateLeftAtXRightAtY ( y, x );
                    if ( q == 0 )
                        * root = w;
                    else
                        q -> child [ dir ] = w;
                }
                else
                {
                    w = x -> child [ 1 ];
                    y -> child [ 0 ] = w;
                    x -> child [ 1 ] = y;
                    SET_PARENT ( x, q );
                    SET_PARENT ( y, x );
                    if ( w != 0 )
                        SET_PARENT ( w, y );
                    if ( q == 0 )
                        * root = x;
                    else
                        q -> child [ dir ] = x;
                    if ( BALANCE ( x ) == 0 )
                    {
                        SET_BALANCE ( x, RIGHT );
                        SET_PARBAL ( y, x, LEFT );
                        return;
                    }
                    ZERO_BALANCE ( x );
                    ZERO_BALANCE ( y );
                    /* y = x; */
                }
                break;
            case RIGHT:
                CLR_BALANCE ( y, RIGHT );
                break;
            }
        }
    }
}