Ejemplo n.º 1
0
/*
 *  check balances and rotate as required. 
 */
static void rebalance(cp_avlnode **node)
{
	if ((*node)->balance == -2)
	{
		if ((*node)->left->balance == 1)
			left_right_rotate(node);
		else
			right_rotate(node);
	}
	else if ((*node)->balance == 2)
	{
		if ((*node)->right->balance == -1)
			right_left_rotate(node);
		else
			left_rotate(node);
	}
}
Ejemplo n.º 2
0
/*******************************************************************************
* Fixes the tree in order to balance it. Basically, we start from 'p_entry'    *
* go up the chain towards parents. If a parent is disbalanced, a set of        *
* rotations are applied. If 'insertion_mode' is on, it means that previous     *  
* modification was insertion of an entry. In such a case we need to perform    *
* only one rotation. If 'insertion_mode' is off, the last operation was        *
* removal and we need to go up until the root node.                            *
*******************************************************************************/  
static void fix_after_modification(map* p_map, 
                                   map_entry* entry,
                                   bool insertion_mode)
{
    map_entry* parent = entry->parent;
    map_entry* grand_parent;
    map_entry* sub_tree;

    while (parent) 
    {
        if (height(parent->left) == height(parent->right) + 2)
        {
            grand_parent = parent->parent;

            if (height(parent->left->left) >= height(parent->left->right)) 
            {
                sub_tree = right_rotate(parent);
            }
            else
            {
                sub_tree = left_right_rotate(parent);
            }
                
            if (!grand_parent) 
            {
                p_map->root = sub_tree;
            }
            else if (grand_parent->left == parent) 
            {
                grand_parent->left = sub_tree;
            }
            else
            {
                grand_parent->right = sub_tree;
            }
             
            if (grand_parent)
            {
                grand_parent->height = 
                        max(height(grand_parent->left),
                                   height(grand_parent->right)) + 1;
            }   

            /* Fixing after insertion requires only one rotation. */
            if (insertion_mode) 
            {
                return;
            }
        }
        else if (height(parent->right) == height(parent->left) + 2) 
        {
            grand_parent = parent->parent;

            if (height(parent->right->right) >= height(parent->right->left)) 
            {
                sub_tree = left_rotate(parent);
            }
            else
            {
                sub_tree = right_left_rotate(parent);
            }
                
            if (!grand_parent)
            {
                p_map->root = sub_tree;
            }
            else if (grand_parent->left == parent)
            {
                grand_parent->left = sub_tree;
            }
            else
            {
                grand_parent->right = sub_tree;
            }
             
            if (grand_parent)
            {   
                grand_parent->height = 
                        max(height(grand_parent->left),
                            height(grand_parent->right)) + 1;
            }

            /* Fixing after insertion requires only one rotation. */
            if (insertion_mode) 
            {
                return;
            }
        }

        parent->height = max(height(parent->left),
                             height(parent->right)) + 1;
        parent = parent->parent;
    }
}