# [置顶] RBTree

683人阅读 评论(0)

0 定义

红黑树是一棵二叉查找树，树中的结点分为外结点和内结点，外结点本质就是一个NIL空指针叶结点，我们一般把外结点忽略画出来，内结点用来存储关键字。结点新增一个颜色域为红色或黑色，满足下列性质：
①每个结点一定是红色或者黑色；
②根结点一定是黑色的；
③每个外结点也是黑色的；
④如果一个内结点是红的，那么两个儿子都是黑色的；
⑤从任意一个内结点出发，到其子孙任意外结点的所有路径的黑结点都相等；

1 旋转

旋转的操作与AVL大同小异，分为左旋转和右旋转两种情况，比较简单，这里就不详说了，C++代码如下：

 //Created by pritry #define RB_RED 0 #define RB_BLACK 1 struct rb_tree {   int color;   int key;   rb_tree* lchild;   rb_tree* rchild;   rb_tree* parent;   //父指针 }; void rb_rotate_left(rb_tree** T, rb_tree* node) {   rb_tree* r = node->rchild;   node->rchild = r->lchild;   if(r->lchild)      r->lchild->parent = node;   r->parent = node->parent;   if(node->parent == NULL)     *T = r;   else if(node->parent->lchild == node)     node->parent->lchild = r;   else     node->parent->rchild = r;     r->lchild = node;   node->parent = r; } void rb_rotate_right(rb_tree** T, rb_tree* node) {   rb_tree* l = node->lchild;   node->lchild = l->rchild;   if(l->rchild)      l->rchild->parent = node;   l->parent = node->parent;   if(node->parent == NULL)     *T = l;   else if(node->parent->lchild == node)     node->parent->lchild = l;   else     node->parent->rchild = l;   l->rchild = node;   node->parent = l; }

2 插入

C++代码如下：

 //Created by pritry void rb_insert_node(rb_tree** T, rb_tree* node) {   rb_tree* p = NULL;   rb_tree* q = *T;   while(q)   {     p = q;     if(node->key < q->key)       q = q->lchild;     else       q = q->rchild;   }   node->parent = p;   if(!p)     *T = node;   else if(node->key < p->key)     p->lchild = node;   else     p->rchild = node;   node->color = RB_RED; } void rb_insert_color(rb_tree** T, rb_tree* node) {   rb_tree* parent;   rb_tree* granpa;   while((parent = node->parent) && RB_RED == parent->color)   {     granpa = parent->parent;     if(granpa && granpa->lchild == parent)     {       rb_tree* uncle = granpa->rchild;       if(uncle && RB_RED == uncle->color)       {         uncle->color = RB_BLACK;         parent->color = RB_BLACK;         granpa->color = RB_RED;         node = granpa;       }       else if(parent->rchild == node)       {         node = parent;         rb_rotate_left(T, node);       }       node->parent->color = RB_BLACK;       granpa->color = RB_RED;       rb_rotate_right(T, granpa);     }     else if(granpa && granpa->rchild == parent)     {       rb_tree* uncle = granpa->lchild;       if(uncle && RB_RED == uncle->color)       {         uncle->color = RB_BLACK;         parent->color = RB_BLACK;         granpa->color = RB_RED;         node = granpa;       }       else if(parent->lchild == node)       {         node = parent;         rb_rotate_right(T, node);       }       node->parent->color = RB_BLACK;       granpa->color = RB_RED;       rb_rotate_left(T, granpa);     }   }   (*T)->color = RB_BLACK; } void rb_insert(rb_tree** T, rb_tree* node) {   rb_insert_node(T, node);   rb_insert_color(T, node); }

3 删除

删除的方法与二叉排序树一样，如果删除掉的是黑色，还需补一个黑色，然后进行分对称的四种情况来进行调节结点颜色，旋转次数不超过三次，这比AVL显然好很多。①node的兄弟sibing是红色；②node的兄弟sibing是黑色，且sibing的两个孩子是黑色；③node的兄弟是黑色，且sibing的两个孩子是红色；④node的兄弟是黑色，且sibing的左孩子是红色，右孩子是黑色；C++代码如下：

 //Created by pritry void rb_delete_color(rb_tree** T, rb_tree* node) {   rb_tree* parent;   rb_tree* sibling;   while(node != *T && RB_BLACK == node->color)   {     parent = node->parent;     if(parent->lchild == node)     {       sibling = parent->rchild;       if(RB_RED == sibling->color)       {         sibling->color = RB_BLACK;         parent->color = RB_RED;         rb_rotate_left(T, parent);         sibling = parent->rchild;       }       if ((!sibling->lchild || RB_BLACK == sibling->lchild->color) &&        (!sibling->rchild || RB_BLACK == sibling->rchild->color))       {         sibling->color = RB_RED;         node = parent;         parent = node->parent;       }       else       {         if(!sibling->rchild || RB_BLACK == sibling->rchild->color)         {           sibling->color = RB_RED;           rb_rotate_right(T, sibling);           sibling = parent->rchild;         }         sibling->color = parent->color;         parent->color = RB_BLACK;         sibling->rchild->color = RB_BLACK;         rb_rotate_left(T, parent);         node = *T;       }     }     else     {       sibling = parent->lchild;       if(RB_RED == sibling->color)       {         sibling->color = RB_BLACK;         parent->color = RB_RED;         rb_rotate_right(T, parent);         sibling = parent->lchild;       }       if ((!sibling->lchild || RB_BLACK == sibling->lchild->color) &&        (!sibling->rchild || RB_BLACK == sibling->rchild->color))       {         sibling->color = RB_RED;         node = parent;         parent = node->parent;       }       else       {         if(!sibling->lchild || RB_BLACK == sibling->lchild->color)         {           sibling->color = RB_RED;           rb_rotate_left(T, sibling);           sibling = parent->lchild;         }         sibling->color = parent->color;         parent->color = RB_BLACK;         sibling->lchild->color = RB_BLACK;         rb_rotate_right(T, parent);         node = *T;       }     }   }   node->color = RB_BLACK; } rb_tree* rb_delete_node(rb_tree** T, rb_tree* node) {   rb_tree* p;   rb_tree* q;   if(node->lchild && node->rchild)   {     rb_tree* left;     p = node->rchild;       while(left = p->lchild)     p = left;   }   else     p = node;   if(p->lchild)     q = p->lchild;   else     q = p->rchild;   q->parent = p->parent;   if(p->parent == NULL)     *T = q;   else if(p->parent->lchild == p)     p->parent->lchild = q;   else      p->parent->rchild = q;   if(p != node) node->key = p->key;   if(RB_BLACK == p->color)     rb_delete_color(T, q);   return p; } rb_tree* rb_delete(rb_tree** T, rb_tree* node) {   return rb_delete_node(T, node); }
0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：354015次
• 积分：4532
• 等级：
• 排名：第6524名
• 原创：79篇
• 转载：181篇
• 译文：0篇
• 评论：21条
评论排行
最新评论