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); }
Node* tree_successor(const Node *n) { Node *p = const_cast<Node*>(n); if (NIL == p) return p; if (NIL != RIGHT(p)) return tree_min(RIGHT(p)); while (IS_RIGHT(p) && (p = PARENT(p))); return PARENT(p); }
int os_rank(const Node *T, const Node *n) { int r = SIZE(LEFT(n)) + 1; Node *p = const_cast<Node*>(n); while (p != T) { if (IS_RIGHT(p)) { r += SIZE(LEFT(PARENT(p))) +1; } p = PARENT(p); } return r; }
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 inorder_tree_walk(const Node *T) { if (NIL == T) return; // 按照两套规则处理:“未经过的节点”和“已经过的节点” Node *p = const_cast<Node*>(T); while (NIL != p) { // ============未经过的节点============= // 左孩子不为空, 则向下遍历左孩子 if (NIL != LEFT(p)) { p = LEFT(p); continue; } // 左孩子为空,则访问本节点 printf("%d(%d), ", KEY(p), SIZE(p)); // 右孩子不为空,则访问右子树 if (NIL != RIGHT(p)) { p = RIGHT(p); continue; } // ============已经过的节点============= // 右孩子为空,则开始向上处理父亲 while (true) { if (IS_RIGHT(p)) { // 如果本节点是父亲的右孩子,则继续向上处理父亲 p = PARENT(p); } else { // 本节点是父亲的左孩子,则访问父亲 p = PARENT(p); printf("%d(%d), ", KEY(p), SIZE(p)); // 如果右孩子不为空,则访问右子树(“未经过的节点”) if (NIL != RIGHT(p)) { p = RIGHT(p); break; } // 右孩子为空,则继续向上处理父亲 } // 如果父亲是根,则意味着访问结束 if (IS_ROOT(p)) return; } } }
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; }