Example #1
0
void make_balance_after_insert(ptr_rbnode node) {
    //case 1 : root node
    if (node->parent == NULL) {
        node->color = BLACK;
        return;
    }
    //case 2 : parent is black
    if (node->parent->color == BLACK) {
        return; //nothing to do
    }
    //now it is guaranteed that node has grandparent
    //case 3 : p and u = red, g = black
    ptr_rbnode g = get_grandparent(node), u = get_uncle(node), p = node->parent;
    assert(g);
    if (p->color == RED && u->color == RED && g->color == BLACK) {
        p->color = BLACK; u->color = BLACK; g->color = RED;
        make_balance_after_insert(g);
        /* this recursive operation will take O(log N) in worst case and O(1) in average case
        because the time complexity distribution would have a form of geometric distribution. */
        return;
    }

    //case 4,5 : p = red, u = black, g = black; -> guaranteed
    //if node, p and g is not on a line, rotate
    //case 4 would be changed into case 5
    assert(p->color == RED && u->color == BLACK && g->color == BLACK);
    if (g->left == p && p->right == node) {
        rotate_left(p);
        node = node->left;
        //for case 5
        g = get_grandparent(node), u = get_uncle(node), p = node->parent;
    }

    else if (g->right == p && p->left == node) {
        rotate_right(p);
        // for case 5
        g = get_grandparent(node), u = get_uncle(node), p = node->parent;
        node = node->right;
    }
    g = get_grandparent(node), u = get_uncle(node), p = node->parent;
    //case 5
    assert((p->left == node && g->left == p)
           || (p->right == node && g->right == p));
    p->color = BLACK;
    g->color = RED;

    if (p->left == node) {
        rotate_right(g);
    }
    else {
        rotate_left(g);
    }
}
Example #2
0
/* W. 2+3) Parent of node must be black, otherwise recolor and flush */
static void insert_check_2 (DLRBT_Tree *tree, DLRBT_Node *node)
{
	/* if the parent is not black, we need to change that... */
	if (node && node->parent && node->parent->tree_col) {
		DLRBT_Node *unc= get_uncle(node);
		
		/* if uncle and parent are both red, need to change them to black and make 
		 * the parent black in order to satisfy the criteria of each node having the
		 * same number of black nodes to its leaves
		 */
		if (unc && unc->tree_col) {
			DLRBT_Node *gp= get_grandparent(node);
			
			/* make the n-1 generation nodes black */
			node->parent->tree_col= unc->tree_col= DLRBT_BLACK;
			
			/* - make the grandparent red, so that we maintain alternating red/black property 
			 *  (it must exist, so no need to check for NULL here),
			 * - as the grandparent may now cause inconsistencies with the rest of the tree, 
			 *   we must flush up the tree and perform checks/rebalancing/repainting, using the 
			 * 	grandparent as the node of interest
			 */
			gp->tree_col= DLRBT_RED;
			insert_check_1(tree, gp);
		}
		else {
			/* we've got an unbalanced branch going down the grandparent to the parent,
			 * so need to perform some rotations to re-balance the tree
			 */
			insert_check_3(tree, node);
		}
	}
}