void rb_insert(rbtree* tree, int data) { rbnode* pn = rb_search(tree, data); rbnode* nn = create_rbnode(data); if (!pn) { tree->root = nn; nn->color = BLACK; return; } else if (data == pn->data) { return; } else if (data < pn->data) { pn->left = nn; nn->parent = pn; } else if (data > pn->data) { pn->right = nn; nn->parent = pn; } while (pn && pn->color == RED) { if (IS_LEFT(pn)) { rbnode* uncle = pn->parent->right; if (uncle && uncle->color == RED) { pn->color = uncle->color = BLACK; pn->parent->color = RED; nn = pn->parent; pn = nn->parent; continue; } if (IS_RIGHT(nn)) { LEFT_ROTATE(tree, pn); SWAP(nn, pn, rbnode*); } RIGHT_ROTATE(tree, pn->parent); pn->color = BLACK; pn->right->color = RED; break; } else { rbnode* uncle = pn->parent->left; if (uncle && uncle->color == RED) { pn->color = uncle->color = BLACK; pn->parent->color = RED; nn = pn->parent; pn = nn->parent; continue; } if (IS_LEFT(nn)) { RIGHT_ROTATE(tree, pn); SWAP(nn, pn, rbnode*); } LEFT_ROTATE(tree, pn->parent); pn->color = BLACK; pn->left->color = RED; break; } } // nn is root if (!pn) nn->color = BLACK; }
void rb_insert_fixup(Node* &T, Node *n) { // 如果n的父亲是红色,则需要调整 // 如果n的父亲是黑色,则不需要调整,因为n本身是红色 while(IS_RED(PARENT(n))) { // 根据n的叔叔节点的颜色,来决定调整方案 Node *p = IS_LEFT(PARENT(n))? RIGHT(PARENT(PARENT(n))): LEFT(PARENT(PARENT(n))); // 如果叔叔是红色,那很简单,把爷爷的黑色转移给父亲和叔叔,爷爷刷成红色 // 这样,即满足了性质4,也没有破坏性质5及其他性质 // 但是,爷爷可能破坏了红黑性质4,则从爷爷开始继续调整(向上递归了两层) if (IS_RED(p)) { // 父亲刷成黑色 SET_BLACK(PARENT(n)); // 叔叔刷成黑色 SET_BLACK(p); // 爷爷刷成红色 SET_RED(PARENT(PARENT(n))); // 从爷爷开始继续调整 n = PARENT(PARENT(n)); continue; } // 如果叔叔是黑色,就复杂一点,引入旋转操作 // 如果n是左孩子,那么需要一次右旋+颜色调整即可 // 如果n是右孩子,则通过一次左旋调整成左孩子,然后按上面情况处理 if (IS_LEFT(PARENT(n))) { // 如果n是右孩子,通过右旋调整成左孩子 if (IS_RIGHT(n)) { n = PARENT(n); left_rotate(T, n); } // 现在n是左孩子了 SET_BLACK(PARENT(n)); SET_RED(PARENT(PARENT(n))); right_rotate(T, PARENT(PARENT(n))); } else { if (IS_LEFT(n)) { n = PARENT(n); right_rotate(T,n); } SET_BLACK(PARENT(n)); SET_RED(PARENT(PARENT(n))); left_rotate(T,PARENT(PARENT(n))); } } // 如果n是根节点,则把根设置为黑色 if (NIL == PARENT(n)) SET_BLACK(n); }
void right_rotate(Node* &T, Node *x) { if (NIL == LEFT(x)) return; Node *y = LEFT(x); // y的右孩子挂到x的左孩子 LEFT(x) = RIGHT(y); if (NIL != RIGHT(y)) PARENT(RIGHT(y)) = x; // x的父亲作为y的父亲 PARENT(y) = PARENT(x); // x是根节点,则y是新的根;否则,把y挂到x的父节点下 if (NIL == PARENT(x)) { T = y; } else if (IS_LEFT(x)) { LEFT(PARENT(x)) = y; } else { RIGHT(PARENT(x)) = y; } // 把x挂到y的右孩子 RIGHT(y) = x; PARENT(x) = y; // 重新计算x和y的max值 MAX(x) = max(MAX(LEFT(x)), MAX(RIGHT(x)), HIGH(KEY(x))); MAX(y) = max(MAX(LEFT(y)), MAX(RIGHT(y)), HIGH(KEY(y))); }
void right_rotate(Node* &T, Node *x) { if (NIL == LEFT(x)) return; Node *y = LEFT(x); // y的右孩子挂到x的左孩子 LEFT(x) = RIGHT(y); if (NIL != RIGHT(y)) PARENT(RIGHT(y)) = x; // x的父亲作为y的父亲 PARENT(y) = PARENT(x); // x是根节点,则y是新的根;否则,把y挂到x的父节点下 if (NIL == PARENT(x)) { T = y; } else if (IS_LEFT(x)) { LEFT(PARENT(x)) = y; } else { RIGHT(PARENT(x)) = y; } // 把x挂到y的右孩子 RIGHT(y) = x; PARENT(x) = y; // 现在开始重新计算各个节点的size // 其实只有x和y的size发生变化 // y的新size不需要计算,就是x的旧size // x的新size,则需要重新计算 SIZE(y) = SIZE(x); SIZE(x) = SIZE(LEFT(x)) + SIZE(RIGHT(x)) + 1; }
Node* tree_predecessor(const Node *n) { Node *p = const_cast<Node*>(n); if (NIL == p) return p; if (NIL != LEFT(p)) return tree_max(LEFT(p)); while(IS_LEFT(p) && (p = PARENT(p))); return PARENT(p); }
static void RIGHT_ROTATE(rbtree* tree, rbnode* n) { int is_left = IS_LEFT(n); int is_right = IS_RIGHT(n); rbnode* l = n->left; l->parent = n->parent; if (is_left) l->parent->left = l; else if (is_right) l->parent->right = l; else tree->root = l; n->left = l->right; if (n->left) n->left->parent = n; l->right = n; n->parent = l; }
static void LEFT_ROTATE(rbtree* tree, rbnode* n) { int is_left = IS_LEFT(n); int is_right = IS_RIGHT(n); rbnode* r = n->right; r->parent = n->parent; if (is_left) r->parent->left = r; else if (is_right) r->parent->right = r; else tree->root = r; n->right = r->left; if (n->right) n->right->parent = n; r->left = n; n->parent = r; }
void tree_delete(Node* &T, Node *x) { if (NIL == T || NIL == x) return; // y是要删除的节点 Node *y = NULL; if ((NIL == LEFT(x)) || (NIL == RIGHT(x))) y = x; else y = tree_successor(x); if (y != x) KEY(x) = KEY(y); // y肯定只有一个孩子 Node * z = (NIL != LEFT(y))? LEFT(y): RIGHT(y); // 即使z是NIL,也给挂上,否则会影响rb_delete_fixup PARENT(z) = PARENT(y); if (NIL == PARENT(y)) { // 根节点发生变化 T = z; } else if (IS_LEFT(y)){ LEFT(PARENT(y)) = z; } else { RIGHT(PARENT(y)) = z; } // 调整路径上节点的max值 Node *p = PARENT(z); while (NIL != p) { MAX(p) = max(MAX(LEFT(p)), MAX(RIGHT(p)), HIGH(KEY(p))); p = PARENT(p); } // 如果y是黑色,说明破坏红黑树的规则;如果y是红色,则不会破坏 if (IS_BLACK(y)) { rb_delete_fixup(T, z); } free_node(y); }
void tree_delete(Node* &T, Node *x) { if (NIL == T || NIL == x) return; // y是要删除的节点 Node *y = NULL; if ((NIL == LEFT(x)) || (NIL == RIGHT(x))) y = x; else y = tree_successor(x); if (y != x) KEY(x) = KEY(y); // y肯定只有一个孩子 Node * z = (NIL != LEFT(y))? LEFT(y): RIGHT(y); // 即使z是NIL,也给挂上,否则会影响rb_delete_fixup PARENT(z) = PARENT(y); if (NIL == PARENT(y)) { // 根节点发生变化 T = z; } else if (IS_LEFT(y)){ LEFT(PARENT(y)) = z; } else { RIGHT(PARENT(y)) = z; } // 沿着y节点向上,更新路径上每个节点的size Node *p = y; while (NIL != (p=PARENT(p))) { SIZE(p)--; } // 如果y是黑色,说明破坏红黑树的规则;如果y是红色,则不会破坏 if (IS_BLACK(y)) { rb_delete_fixup(T, z); } free_node(y); }
static inline void node_rotate_left(map_t *map, mapnode_t *node) { mapnode_t *right = node->right; node->right = right->left; if (node->right != NIL) node->right->parent = node; right->parent = node->parent; if (node->parent == NIL) { map->root = right; } else { if (IS_LEFT(node)) { node->parent->left = right; } else { node->parent->right = right; } } right->left = node; node->parent = right; }
void map_insert(map_t *map, mapkey_t key, void *p) { allocator_t *alloc = map->allocator; mapnode_t *parent = map->root; mapnode_t **slot = &map->root; mapnode_t *insert; while (parent != NIL) { int comparison = map->ops.compare_key(key, parent->key); if (comparison == 0) { map->ops.destroy_value(parent->p, alloc); parent->p = map->ops.copy_value(p, alloc); return; } else if (comparison < 0) { if (parent->left != NIL) { parent = parent->left; continue; } else { slot = &parent->left; break; } } else { if (parent->right != NIL) { parent = parent->right; continue; } else { slot = &parent->right; break; } } } map->size += 1; insert = (mapnode_t *)com_malloc(map->allocator, sizeof(mapnode_t)); insert->left = insert->right = NIL; insert->key = map->ops.copy_key(key, alloc); insert->p = map->ops.copy_value(p, alloc); insert->color = RED; insert->parent = parent; *slot = insert; while (IS_RED(insert->parent) && node_grandparent(insert) != NIL) { mapnode_t *uncle = node_sibling(insert->parent); if (IS_RED(uncle)) { insert->parent->color = BLACK; uncle->color = BLACK; uncle->parent->color = RED; insert = uncle->parent; } else { int insleft = IS_LEFT(insert); int parleft = IS_LEFT(insert->parent); if (!insleft && parleft) { insert = insert->parent; node_rotate_left(map, insert); } else if (insleft && !parleft) { insert = insert->parent; node_rotate_right(map, insert); } insert->parent->parent->color = RED; insert->parent->color = BLACK; if (parleft) node_rotate_right(map, insert->parent->parent); else node_rotate_left(map, insert->parent->parent); } } map->root->color = BLACK; #if !defined(NDEBUG) map_test(map->root); #endif }
static inline mapnode_t *node_sibling(mapnode_t *node) { if (node->parent == NIL) return NIL; return IS_LEFT(node) ? node->parent->right : node->parent->left; }
void rb_delete(rbtree* tree, int data) { int color = RED; rbnode* dn = tree->root; rbnode* x = 0; rbnode* y = 0; //parent of deleted node rbnode* s = 0; //sibling rbnode* p = 0; //parent rbnode* ln =0; //left nephew rbnode* rn = 0; //right nephew int delcolor = 0; while (dn) { if (dn->data == data) break; else if (data < dn->data) dn = dn->left; else dn = dn->right; } if (!dn) return; delcolor = dn->color; y = dn->parent; if (!dn->left && !dn->right) { REPLACE(tree, dn, ((rbnode*)0)); x = 0; } else if (!dn->left) { REPLACE(tree, dn, dn->right); x = dn->right; } else if (!dn->right) { REPLACE(tree, dn, dn->left); x = dn->left; } else { rbnode* rl = dn->right; while (rl->left) rl = rl->left; x = rl->right; y = rl == dn->right ? rl : rl->parent; delcolor = rl->color; REPLACE(tree, rl, rl->right); REPLACE(tree, dn, rl); rl->left = dn->left; rl->right = dn->right; rl->color = dn->color; } if (delcolor == RED) { destory_rbnode(dn); return; } while (IS_BLACK(x) && x != tree->root) { p = x ? x->parent : y; if ((!x && !y->left) || IS_LEFT(x)) { s = p->right;//s != 0,because x is black, the path to from s to null must has at least a black node if (s->color == RED) { LEFT_ROTATE(tree,p); p->color = RED; s->color = BLACK; continue; } else if (IS_BLACK(s->left) && IS_BLACK(s->right)) { s->color = RED; x = p; continue; } ln = s->left; rn = s->right; if (IS_BLACK(rn)) { RIGHT_ROTATE(tree,s); s->color = RED; ln->color = BLACK; continue; } else { LEFT_ROTATE(tree,p); s->color = p->color; p->color = BLACK; x = rn; break; } } else if ((!x && !y->right) || IS_RIGHT(x)) { s = p->left;//s != 0,because x is black, the path to from s to null must has at least a black node if (s->color == RED) { RIGHT_ROTATE(tree,p); p->color = RED; s->color = BLACK; continue; } else if (IS_BLACK(s->left) && IS_BLACK(s->left)) { s->color = RED; x = p; continue; } ln = s->left; rn = s->left; if (IS_BLACK(ln)) { LEFT_ROTATE(tree,s); s->color = RED; rn->color = BLACK; continue; } else { RIGHT_ROTATE(tree,p); s->color = p->color; p->color = BLACK; x = ln; break; } } } if (x) x->color = BLACK; destory_rbnode(dn); return; }
void rb_delete_fixup(Node* &T, Node *x) { while ((NIL!= x) && !IS_ROOT(x) && IS_BLACK(x)) { if (IS_LEFT(x)) { // w是x的右兄弟,w是下面不同处理方式的选择依据 // 总共四种处理方式: // case 1: w是红色,两个孩子的颜色无所谓 // case 2: w是黑色,左孩子黑色,右孩子黑色 // case 3: w是黑色,左孩子红色,右孩子黑色 // case 4: w是黑色,右孩子红色,左孩子的颜色无所谓 Node *w = RIGHT(PARENT(x)); // case1: w是红色,则通过一次左旋,并刷成黑色,转成case 2、3、4 if (IS_RED(w)) { SET_BLACK(w); SET_RED(PARENT(x)); left_rotate(T, PARENT(x)); } // case 2: w的两个孩子都是黑色,把w刷成红色,x的父亲取代x,向上递归处理 if (IS_BLACK(LEFT(w)) && IS_BLACK(RIGHT(w))) { SET_RED(w); x = PARENT(x); continue; } // case 3: w的左孩子红色,右孩子黑色,把w左孩子刷成黑色,w刷成红色,做一次右旋,转成case 4 if (IS_BLACK(RIGHT(w))) { SET_BLACK(LEFT(w)); SET_RED(w); right_rotate(T, w); w = PARENT(w); // 转成case 4 } // case 4: w的右孩子为红色,把w刷成红色,w右节点刷成黑色,x父亲刷成黑色,做一次左旋,满足红黑性质,结束处理 COLOR(w) = COLOR(PARENT(x)); SET_BLACK(RIGHT(w)); SET_BLACK(PARENT(x)); left_rotate(T, PARENT(x)); x = T; } else { // w是x的左兄弟,w是下面不同处理方式的选择依据 // 总共四种处理方式: // case 1: w是红色,两个孩子的颜色无所谓 // case 2: w是黑色,左孩子黑色,右孩子黑色 // case 3: w是黑色,左孩子红色,右孩子黑色 // case 4: w是黑色,右孩子红色,左孩子的颜色无所谓 Node *w = LEFT(PARENT(x)); // case1: w是红色,则通过一次右旋,并刷成黑色,转成case 2、3、4 if (IS_RED(w)) { SET_BLACK(w); SET_RED(PARENT(x)); right_rotate(T, PARENT(x)); } // case 2: w的两个孩子都是黑色,把w刷成红色,x的父亲取代x,线上递归处理 if (IS_BLACK(LEFT(w)) && IS_BLACK(RIGHT(w))) { SET_RED(w); x = PARENT(x); continue; } // case 3: w的左孩子黑色,右孩子红色,把w右孩子刷成黑色,w刷成红色,做一次左旋,转成case 4 if (IS_BLACK(LEFT(w))) { SET_BLACK(RIGHT(w)); SET_RED(w); left_rotate(T, w); w = PARENT(w); // 转成case 4 } // case 4: w的左孩子为红色,把w刷成红色,w左节点刷成黑色,x父亲刷成黑色,做一次右旋,满足红黑性质,结束处理 COLOR(w) = COLOR(PARENT(x)); SET_BLACK(LEFT(w)); SET_BLACK(PARENT(x)); right_rotate(T, PARENT(x)); x = T; } } // 如果x是根节点,或为红色,则都刷成黑色,即可保持红黑树性质 SET_BLACK(x); }