/* * Operations INSERT and DELETE, when run on a tree with n keys, * take O(logN) time.Because they modify the tree, the result * may violate the red-black properties.To restore these properties, * we must change the colors of some of the nodes in the tree * and also change the pointer structure. */ static void interval_insert_color(struct interval_node *node, struct interval_node **root) { struct interval_node *parent, *gparent; while ((parent = node->in_parent) && node_is_red(parent)) { gparent = parent->in_parent; /* Parent is RED, so gparent must not be NULL */ if (node_is_left_child(parent)) { struct interval_node *uncle; uncle = gparent->in_right; if (uncle && node_is_red(uncle)) { uncle->in_color = INTERVAL_BLACK; parent->in_color = INTERVAL_BLACK; gparent->in_color = INTERVAL_RED; node = gparent; continue; } if (parent->in_right == node) { __rotate_left(parent, root); interval_swap(node, parent); } parent->in_color = INTERVAL_BLACK; gparent->in_color = INTERVAL_RED; __rotate_right(gparent, root); } else { struct interval_node *uncle; uncle = gparent->in_left; if (uncle && node_is_red(uncle)) { uncle->in_color = INTERVAL_BLACK; parent->in_color = INTERVAL_BLACK; gparent->in_color = INTERVAL_RED; node = gparent; continue; } if (node_is_left_child(node)) { __rotate_right(parent, root); interval_swap(node, parent); } parent->in_color = INTERVAL_BLACK; gparent->in_color = INTERVAL_RED; __rotate_left(gparent, root); } } (*root)->in_color = INTERVAL_BLACK; }
static void __remove(treap_head **pp) { assert(pp); while (1) { if (!pp || !*pp) return; else if (!(*pp)->left && !(*pp)->right) { *pp = (*pp)->parent = NULL; } else if (!(*pp)->left) { __rotate_left(pp); pp = &(*pp)->left; } else if (!(*pp)->right) { __rotate_right(pp); pp = &(*pp)->right; } else if ((*pp)->left->priority > (*pp)->right->priority) { __rotate_right(pp); pp = &(*pp)->right; } else { __rotate_left(pp); pp = &(*pp)->left; } } }
treap_head * treap_insert(treap_tree *tree, treap_head *node) { unsigned long key; treap_head **pp, *parent; assert(tree && node); if (!tree || !node) return null_head; treap_init(node); key = __TREAP_KEY(tree, node); parent = tree->root; pp = &tree->root; while (*pp) { int __cmp = __TREAP_CMP(tree, key, __TREAP_KEY(tree, *pp)); if (__cmp == 0 && tree->unique) return null_head; if (__cmp <= 0) { parent = *pp; pp = &(*pp)->left; } else { parent = *pp; pp = &(*pp)->right; } } *pp = node; node->parent = parent; while (1) { if (!*pp) return node; else if ((*pp)->left && (*pp)->left->priority > (*pp)->priority) __rotate_right(pp); else if ((*pp)->right && (*pp)->right->priority > (*pp)->priority) __rotate_left(pp); if (!(*pp)->parent) return node; else if (!(*pp)->parent->parent) pp = &tree->root; else if ((*pp)->parent == (*pp)->parent->parent->left) pp = &(*pp)->parent->parent->left; else if ((*pp)->parent == (*pp)->parent->parent->right) pp = &(*pp)->parent->parent->right; } return node; }
static void interval_erase_color(struct interval_node *node, struct interval_node *parent, struct interval_node **root) { struct interval_node *tmp; while (node_is_black_or_0(node) && node != *root) { if (parent->in_left == node) { tmp = parent->in_right; if (node_is_red(tmp)) { tmp->in_color = INTERVAL_BLACK; parent->in_color = INTERVAL_RED; __rotate_left(parent, root); tmp = parent->in_right; } if (node_is_black_or_0(tmp->in_left) && node_is_black_or_0(tmp->in_right)) { tmp->in_color = INTERVAL_RED; node = parent; parent = node->in_parent; } else { if (node_is_black_or_0(tmp->in_right)) { struct interval_node *o_left; o_left = tmp->in_left; if (o_left) o_left->in_color = INTERVAL_BLACK; tmp->in_color = INTERVAL_RED; __rotate_right(tmp, root); tmp = parent->in_right; } tmp->in_color = parent->in_color; parent->in_color = INTERVAL_BLACK; if (tmp->in_right) tmp->in_right->in_color = INTERVAL_BLACK; __rotate_left(parent, root); node = *root; break; } } else { tmp = parent->in_left; if (node_is_red(tmp)) { tmp->in_color = INTERVAL_BLACK; parent->in_color = INTERVAL_RED; __rotate_right(parent, root); tmp = parent->in_left; } if (node_is_black_or_0(tmp->in_left) && node_is_black_or_0(tmp->in_right)) { tmp->in_color = INTERVAL_RED; node = parent; parent = node->in_parent; } else { if (node_is_black_or_0(tmp->in_left)) { struct interval_node *o_right; o_right = tmp->in_right; if (o_right) o_right->in_color = INTERVAL_BLACK; tmp->in_color = INTERVAL_RED; __rotate_left(tmp, root); tmp = parent->in_left; } tmp->in_color = parent->in_color; parent->in_color = INTERVAL_BLACK; if (tmp->in_left) tmp->in_left->in_color = INTERVAL_BLACK; __rotate_right(parent, root); node = *root; break; } } } if (node) node->in_color = INTERVAL_BLACK; }
static void __rb_del_fix(rbtree_t *T, rbtree_node_t *x) { rbtree_node_t *w; while ((x != T->root) && (COLOR(x) == BLACK)) { if (x == x->p->l) { w = x->p->r; if (COLOR(w) == RED) { MAKE_BLACK(w); MAKE_RED (x->p); __rotate_left(T, x->p); w = x->p->r; } if ((COLOR(w->l) == BLACK) && (COLOR(w->r) == BLACK)) { MAKE_RED(w); x = x->p; } else { if (COLOR(w->r) == BLACK) { MAKE_BLACK(w->l); MAKE_RED (w); __rotate_right(T, w); w = x->p->r; } w->color = COLOR(x->p); MAKE_BLACK(x->p); MAKE_BLACK(w->r); __rotate_left(T, x->p); x = T->root; break; } } else { w = x->p->l; if (COLOR(w) == RED) { MAKE_BLACK(w); MAKE_RED (x->p); __rotate_right(T, x->p); w = x->p->l; } if ((COLOR(w->l) == BLACK) && (COLOR(w->r) == BLACK)) { MAKE_RED(w); x = x->p; } else { if (COLOR(w->l) == BLACK) { MAKE_BLACK(w->r); MAKE_RED (w); __rotate_left(T, w); w = x->p->l; } w->color = COLOR(x->p); MAKE_BLACK(x->p); MAKE_BLACK(w->l); __rotate_right(T, x->p); x = T->root; break; } } } MAKE_BLACK(x); }
static void __rb_insert (rbtree_t *T, PyObject *k, PyObject *v) { rbtree_node_t *x, *y; Py_INCREF(k); Py_INCREF(v); x = __tree_insert(T, k, v); if (x == NULL) { return; } MAKE_RED (x); while ((x != T->root) && (COLOR(x->p) == RED)) { if (x->p == x->p->p->l) { y = x->p->p->r; if (COLOR(y) == RED) { MAKE_BLACK(x->p); MAKE_BLACK(y); MAKE_RED (x->p->p); x = x->p->p; } else { if (x == x->p->r) { x = x->p; __rotate_left(T, x); } MAKE_BLACK(x->p); MAKE_RED (x->p->p); __rotate_right(T, x->p->p); break; } } else { y = x->p->p->l; if (COLOR(y) == RED) { MAKE_BLACK(x->p); MAKE_BLACK(y); MAKE_RED (x->p->p); x = x->p->p; } else { if (x == x->p->l) { x = x->p; __rotate_right(T, x); } MAKE_BLACK(x->p); MAKE_RED (x->p->p); __rotate_left(T, x->p->p); break; } } } MAKE_BLACK(T->root); }