Because the red-black tree is very interesting to see the kernel, so use the time of the weekend to achieve a play. The operation of the red-black tree is mainly inserted and deleted, and the need to consider more when deleting. The specific operation is not here wordy, Baidu Library has a relatively good article, has said very clearly.
Some people may feel that something is not taken into account when looking at a specific operation (if the person without the feeling is likely not to think carefully at all). But if the "omission" situation exists, the red-black tree before the operation will violate those rules.
Write code many times because less consideration of the situation and lead to errors, more details, just start rb_node not point to the parent node of the pointer, write fast vomiting blood, and then or Add. The exact meaning of the code can be combined with articles and comments (well understood). The following code may also have no details to consider, welcome to pat Bricks.
#include <stdio.h>
#include <stdlib.h>
const int RED = 0;
const int black = 1;
struct rb_node{
rb_node* lchild, *rchild, *parent;
int key, colour;
};
rb_node* Root;
Rb_node* Get_node (rb_node* parent, int key);
void Rb_insert (int key);
rb_node* rb_search (int key);
void Rb_delete (int key);
rb_node* clock_wise (rb_node* node);
rb_node* counter_clock_wise (rb_node* node);
void Show_rb_tree (rb_node* node);
Rb_node* Get_node (rb_node* parent, int key) {
Rb_node *tmp = (rb_node*) malloc (sizeof (Rb_node));
Tmp->key = key;
Tmp->colour = RED;
Tmp->parent = parent;
Tmp->lchild = Tmp->rchild = NULL;
return TMP;
}
rb_node* clock_wise (rb_node* node) {
if (node = null | | node->lchild = NULL)
return NULL;
Rb_node *rb_1=node, *rb_2=node->lchild, *rb_3=node->lchild->rchild;
if (rb_1->parent!= NULL) {
if (Rb_1->parent->lchild = = rb_1)
Rb_1->parent->lchild = rb_2;
Else
Rb_1->parent->rchild = rb_2;
}else if (rb_1 = = root) {
root = rb_2;
}
Rb_2->parent = rb_1->parent;
Rb_1->parent = rb_2;
Rb_2->rchild = rb_1;
Rb_1->lchild = Rb_3;
if (rb_3!= NULL) rb_3->parent = rb_1;
return rb_2;
}
rb_node* counter_clock_wise (rb_node* node) {
if (node = null | | node->rchild = NULL)
return NULL;
Rb_node *rb_1=node, *rb_2=node->rchild, *rb_3=node->rchild->lchild;
if (rb_1->parent!= NULL) {
if (Rb_1->parent->lchild = = rb_1)
Rb_1->parent->lchild = rb_2;
Else
Rb_1->parent->rchild = rb_2;
}
else if (rb_1 = = root) {
root = rb_2;
}
Rb_2->parent = rb_1->parent;
Rb_1->parent = rb_2;
Rb_2->lchild = rb_1;
Rb_1->rchild = Rb_3;
if (rb_3!= NULL) rb_3->parent = rb_1;
return rb_2;
}
rb_node* rb_search (int key) {
Rb_node *p = root;
while (P!= NULL) {
if (Key < P->key)
p = p->lchild;
else if (Key > P->key)
p = p->rchild;
Else
Break
}
return p;
}
void Rb_insert (int key) {
Rb_node *p=root, *q=null;
if (root = = NULL) {
Root = Get_node (NULL, key);
Root->colour = black;
Return
}
while (P!= NULL) {
Q = p;
if (Key < P->key)
p = p->lchild;
else if (Key > P->key)
p = p->rchild;
else return;
}
if (Key < Q->key)
Q->lchild = Get_node (q, key);
Else
Q->rchild = Get_node (q, key);
while (q!= NULL && q->colour = = RED) {
p = q->parent;//p won ' t null, or BUG.
if (p->lchild = = q) {
if (q->rchild!= NULL && q->rchild->colour = = RED)
Counter_clock_wise (q);
Q = clock_wise (p);
Q->lchild->colour = black;
}
else{
if (q->lchild!= NULL && q->lchild->colour = = RED)
Clock_wise (q);
Q = counter_clock_wise (p);
Q->rchild->colour = black;
}
Q = q->parent;
}
Root->colour = black;
}
void Show_rb_tree (rb_node* node) {
if (node = NULL)
Return
printf ("(%d,%d) \ n", Node->key, Node->colour);
if (node->lchild!= NULL) {
printf ("[ -1]\n");
Show_rb_tree (Node->lchild);
}
if (node->rchild!= NULL) {
printf ("[1]\n");
Show_rb_tree (Node->rchild);
}
printf ("[0]\n");
}
void Rb_delete (int key) {
Rb_node *v = Rb_search (key), *u, *p, *c, *b;
int tmp;
if (v = = NULL) return;
U = V;
if (v->lchild!= null && v->rchild!= null) {
U = v->rchild;
while (U->lchild!= NULL) {
U = u->lchild;
}
TMP = u->key;
U->key = v->key;
V->key = tmp;
}
U is the node to free.
if (U->lchild!= NULL)
c = u->lchild;
Else
c = u->rchild;
p = u->parent;
if (P!= NULL) {
Remove u from Rb_tree.
if (p->lchild = u)
P->lchild = C;
Else
P->rchild = C;
}
else{
U is root.
root = C;
Free ((void*) u);
Return
}
You are not root and u are RED, this would not unbalance.
if (U->colour = = RED) {
Free ((void*) u);
Return
}
Free ((void*) u);
U = C;
You are the the "the" "balance."
while (U!= root) {
if (U!= NULL && u->colour = = RED) {
If you are RED, change it to Black can finsh.
U->colour = black;
Return
}
if (U = = p->lchild)
b = p->rchild;
Else
b = p->lchild;
printf ("%d\n", B->key);
B is borther a U. B can ' t be null, or the rb_tree are must not balance.
if (B->colour = black) {
If B ' s son is RED, rotate the node.
if (b->lchild!= NULL && b->lchild->colour = = RED) {
if (U = = p->lchild) {
b = Clock_wise (b);
B->colour = black;
B->rchild->colour = RED;
p = counter_clock_wise (p);
P->colour = p->lchild->colour;
P->lchild->colour = black;
P->rchild->colour = black;
}
else{
p = clock_wise (p);
P->colour = p->rchild->colour;
P->rchild->colour = black;
P->lchild->colour = black;
}
Return
}
else if (b->rchild!= NULL && b->rchild->colour = = RED) {
if (U = = p->rchild) {
b = Counter_clock_wise (b);
B->colour = black;
B->lchild->colour = RED;
p = clock_wise (p);
P->colour = p->rchild->colour;
P->rchild->colour = black;
P->lchild->colour = black;
}
else{
p = counter_clock_wise (p);
P->colour = p->lchild->colour;
P->lchild->colour = black;
P->rchild->colour = black;
}
Return
}
else{//if B ' s sons are black, make B RED and move up U.
B->colour = RED;
U = P;
p = u->parent;
Continue
}
}
else{
if (U = = p->lchild) {
p = counter_clock_wise (p);
P->colour = black;
P->lchild->colour = RED;
p = p->lchild;
}
else{
p = clock_wise (p);
P->colour = black;
P->rchild->colour = RED;
p = p->rchild;
}
}
}
Root->colour = black;
}
int main () {
int i;
root = NULL;
for (i = 1; I <= i++) {
Rb_insert (i);
}
Rb_delete (9);
Rb_delete (3);
Rb_delete (7);
Show_rb_tree (root);
printf ("\ n");
return 0;
}