Exemple #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);
    }
}
Exemple #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);
		}
	}
}
Exemple #3
0
/* W. 4+5) Perform rotation on sub-tree containing the 'new' node, then do any  */
static void insert_check_3(DLRBT_Tree *tree, DLRBT_Node *node)
{
  DLRBT_Node *gp = get_grandparent(node);

  /* check that grandparent and node->parent exist
   * (jut in case... really shouldn't happen on a good tree) */
  if (node && node->parent && gp) {
    /* a left rotation will switch the roles of node and its parent, assuming that
     * the parent is the left child of the grandparent... otherwise, rotation direction
     * should be swapped
     */
    if ((node == node->parent->right) && (node->parent == gp->left)) {
      rotate_left(tree, node);
      node = node->left;
    }
    else if ((node == node->parent->left) && (node->parent == gp->right)) {
      rotate_right(tree, node);
      node = node->right;
    }

    /* fix old parent's color-tagging, and perform rotation on the old parent in the
     * opposite direction if needed for the current situation
     * NOTE: in the code above, node pointer is changed to point to the old parent
     */
    if (node) {
      /* get 'new' grandparent (i.e. grandparent for old-parent (node)) */
      gp = get_grandparent(node);

      /* modify the coloring of the grandparent and parent
       * so that they still satisfy the constraints */
      node->parent->tree_col = DLRBT_BLACK;
      gp->tree_col = DLRBT_RED;

      /* if there are several nodes that all form a left chain, do a right rotation to correct
       * this (or a rotation in the opposite direction if they all form a right chain) */
      if ((node == node->parent->left) && (node->parent == gp->left)) {
        rotate_right(tree, gp);
      }
      else {  // if ((node == node->parent->right) && (node->parent == gp->right))
        rotate_left(tree, gp);
      }
    }
  }
}
Exemple #4
0
int main() {
	srand(time(NULL));
	node* tree = create_bst(40);
	for(uint i = 0; i < 10; ++i) {
		int elem = rand() % 100 + 1;
		insert(&tree, elem);
	}
	insert(&tree, 1337);
	display_tree(tree);
	node* test = search(tree, 1337);
	printf("Grandparent of 1337 is: %d", get_grandparent(tree, test)->data);
	return 0;
}
Exemple #5
0
/* get the 'uncle' - the sibling of the parent - of the given node */
static DLRBT_Node *get_uncle (DLRBT_Node *node)
{
	DLRBT_Node *gpn= get_grandparent(node);
	
	/* return the child of the grandparent which isn't the node's parent */
	if (gpn) {
		if (gpn->left == node->parent)
			return gpn->right;
		else
			return gpn->left;
	}
	
	/* not found */
	return NULL;
}
Exemple #6
0
ptr_rbnode get_uncle(ptr_rbnode node) {
    ptr_rbnode g = get_grandparent(node);
    if (g) {
        if (g->left == node->parent) {
            return g->right;
        }
        else if (g->right == node->parent) {
            return g->left;
        }
        else {
            assert(0 && "Tree Collapsed");
        }
    }
    else
        return NULL;
}