Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1852820
  • 博文数量: 184
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2388
  • 用 户 组: 普通用户
  • 注册时间: 2016-12-21 22:26
个人简介

90后空巢老码农

文章分类

全部博文(184)

文章存档

2021年(26)

2020年(56)

2019年(54)

2018年(47)

2017年(1)

我的朋友

分类: C/C++

2018-09-05 21:44:41

这里先来说一下上篇文章没有说到的地方,在stl中,插入红黑树返回的是一个pair, 其中第二个元素表示成功与否,第一个元素表示插入成功的元素对应的迭代器或者插入失败(已经存在的键)的旧的迭代器~

好了,开始今天的主题——红黑树的删除操作~~~

首先,来回顾一下红黑树的性质,这东西是要时刻记在脑袋里面的:

1. 每一个节点多出一个关于颜色的性质:非黑即红

2. 根节点是黑色的

3. 每一个叶子节点(NULL)视为黑色

4. 如果一个节点为红色,那么它的两个孩子的颜色必须都为黑色

5. 对于任意节点来说,从其开始,至其任意子孙当中的叶子结点的每一条路径当中,所包含的黑色节点数目相同。

对于删除操作,对于二叉搜索树来讲,只需要考虑以下三种情况中的前两种,因为第三种可以将当前要删除节点的值与其后继节点的值相互调换,之后转变为情况1,或者情况2

1)      叶子结点

2)      只有一个孩子不为空

3)      两个孩子都不为空

这样的话,如果要删除一个节点,就先按照正常的二叉搜索树来删除掉该节点,并且

记录注删除节点的颜色,以及递补上来节点的颜色(NULL视为黑色);如果我们只是如此的话,就可能会违背红黑树的性质2,4, 5。对于以上的情况,算法导论里面提出了一个“额外黑色”的概念,即如果被删除的节点的颜色为黑,需要将其原来的黑色额外的加入到递补上来的节点的颜色上,如果递补上来的颜色为红色,那么直接将其变为黑色即可,如果递补进来的节点为黑色,则黑色和额外的黑色无法累加,需要进行如下四张图的调整(调整的时候要看兄弟节点的颜色,且x为递补上来的节点,s为其兄弟节点):其中四张图的顺序依次为兄弟节点为红色、兄弟节点为黑色且两个侄子均为黑色、兄弟节点为黑色且近侄子为红色、兄弟节点为黑色且远侄子为红色,其中,只有情况4是可以肯定使得这个递归过程彻底结束的,所以,其他三种情况应该及可能的向其形式靠拢~

当递补上来的节点的兄弟节点为红色时,由于从根本上来讲,A的实际黑高比D(即C和E)低1,通过变换颜色以及旋转无法直接解决问题,,所以需要将x的兄弟变为黑色,以便后续求解,同时,需要保证B的parent的该子树下的黑高尽可能不变;

x的兄弟节点为黑色,且两个侄子的颜色均为黑色的时候,最简单的做法就是将兄弟节点的颜色变为红色,x指向其父节点,递归向上,去除“额外的黑色”



由于下面一种情况是比较好解决的,所以这种情况就需要委屈一下,尽量变为下边一种情况喽~这里不要害怕E的颜色为红色,因为在下一步操作中,D的颜色会被变为黑色的~


这种情况是肯定会终止的,现在Ce, f 的黑高与A相同,Bparent的该方向的子树的黑高为:BH(A) + 1 + B->color==BLACK?1:0;BH(D)

但是A所在的子树理应多出一个黑高才能使之结束,这样,就将BD颜色对调,E的颜色置为黑色,对B再进行一次左旋就行了~

整个红黑树以及测试代码奉上:

点击(此处)折叠或打开

  1. #include <iostream>

  2. using namespace std;
  3. struct RB_tree_node{
  4.     int val;
  5.     bool color;// false: red; true: black
  6.     struct RB_tree_node *parent;
  7.     struct RB_tree_node *lchild;
  8.     struct RB_tree_node *rchild;
  9.     RB_tree_node(int value):val(value), color(false), parent(NULL), lchild(NULL), rchild(NULL){}
  10. };
  11. struct RB_tree_node *root = NULL;
  12. struct RB_tree_node *Left_Rotate(struct RB_tree_node *x){
  13.     struct RB_tree_node *y = x->rchild;
  14.     bool flag = false;
  15.     if( root == x) flag = true;
  16.     x->rchild = y->lchild;
  17.     if( y->lchild != NULL) y->lchild->parent = x;
  18.     y->parent = x->parent;
  19.     if( !flag ){
  20.         if( x == x->parent->lchild)x->parent->lchild = y;
  21.         else x->parent->rchild= y;
  22.     }
  23.     y->lchild = x;
  24.     x->parent = y;
  25.     if(flag) root = y;
  26.     return y;
  27. }
  28. struct RB_tree_node *Right_Rotate(struct RB_tree_node *y){
  29.     struct RB_tree_node *x = y->lchild;
  30.     bool flag =false;
  31.     if( y == root) flag = true;
  32.     y->lchild = x->rchild;
  33.     if(x->rchild != NULL) x->rchild->parent = y;
  34.     x->parent = y->parent;
  35.     if(!flag){
  36.         if( y==y->parent->lchild) y->parent->lchild = x;
  37.         else y->parent->rchild = x;
  38.     }
  39.     x->rchild = y;
  40.     y->parent = x;
  41.     if(flag) root = x;
  42.     return x;
  43. }
  44. struct RB_tree_node *Get_Sibling(struct RB_tree_node *cur){
  45.     if( cur->parent == NULL) return NULL;
  46.     if( cur == cur->parent->lchild) return cur->parent->rchild;
  47.     else return cur->parent->lchild;
  48. }
  49. struct RB_tree_node *Get_Uncle(struct RB_tree_node *cur){
  50.     if(cur->parent == NULL) return NULL;
  51.     else return(Get_Sibling(cur->parent));
  52. }
  53. void insert_fix( struct RB_tree_node *cur){
  54.     while(cur->parent != NULL && cur->parent->color == false){
  55.         if(cur->parent == cur->parent->parent->lchild){
  56.             struct RB_tree_node *uncle = Get_Uncle(cur);
  57.             if(uncle != NULL && uncle->color == false){
  58.                 cur->parent->color = true;
  59.                 uncle->color = true;
  60.                 cur->parent->parent->color = false;
  61.                 cur = cur->parent->parent;
  62.             }
  63.             else{
  64.                 if(cur == cur->parent->rchild){//内插,需要多一步旋转
  65.                     Left_Rotate(cur->parent);
  66.                     cur=cur->lchild;
  67.                 }
  68.                 //外插情况
  69.                 cur->parent->color = true;
  70.                 cur->parent->parent->color = false;
  71.                 Right_Rotate(cur->parent->parent);
  72.             }
  73.         }else{//父节点是祖节点的右孩子
  74.             struct RB_tree_node *uncle = Get_Uncle(cur);
  75.             if(uncle != NULL && uncle->color == false){
  76.                 cur->parent->color = true;
  77.                 uncle->color = true;
  78.                 cur->parent->parent->color = false;
  79.                 cur = cur->parent->parent;
  80.             }
  81.             else{
  82.                 if(cur == cur->parent->lchild){//内插,需要多一步旋转
  83.                     Right_Rotate(cur->parent);
  84.                     cur=cur->rchild;
  85.                 }
  86.                 //外插情况
  87.                 cur->parent->color = true;
  88.                 cur->parent->parent->color = false;
  89.                 Left_Rotate(cur->parent->parent);
  90.             }
  91.         }
  92.     }
  93.     root->color = true;
  94. }
  95. void insert(int val){
  96.     struct RB_tree_node *cur = new RB_tree_node(val);
  97.     if( root == NULL){
  98.         cur->color = true; root = cur; return;
  99.     }
  100.     struct RB_tree_node *x = root, *y;
  101.     while(x != NULL){
  102.         y=x;
  103.         if (val < x->val) x = x->lchild;
  104.         else x = x->rchild;
  105.     }
  106.     if( val < y->val) y->lchild = cur;
  107.     else y->rchild = cur;
  108.     cur->parent = y;
  109.     if( y->color == false)insert_fix(cur);
  110. }
  111. struct RB_tree_node *Find(int val){
  112.     struct RB_tree_node *cur = root;
  113.     while( cur ){
  114.         if(cur->val == val) break;
  115.         else if(cur->val > val) cur = cur->lchild;
  116.         else cur = cur->rchild;
  117.     }
  118.     return cur;
  119. }
  120. void Transplant(struct RB_tree_node *u, struct RB_tree_node *v){
  121.     if( u->parent == NULL) root = v;
  122.     else if(u == u->parent->lchild) u->parent->lchild = v;
  123.     else u->parent->rchild = v;
  124.     if(v) v->parent = u->parent;
  125. }
  126. void Delete_fix(struct RB_tree_node *x){
  127.     while(x != root && x->color == true){
  128.         if(x == x->parent->lchild){
  129.             struct RB_tree_node *w = x->parent->rchild;
  130.             if( w->color == false){
  131.                 w->color = true;
  132.                 x->parent->color = false;
  133.                 Left_Rotate(x->parent);
  134.                 w = x->parent->rchild;
  135.             }
  136.             if( w->lchild->color==true && w->rchild->color == true){
  137.                 w->color = false;x = x->parent;
  138.             }else{
  139.                 if(w->rchild->color == true){
  140.                     w->lchild->color = true;
  141.                     w->color = false;
  142.                     Right_Rotate(w);
  143.                     w = x->parent->rchild;
  144.                 }
  145.                 w->color = x->parent->color;
  146.                 x->parent->color = true;
  147.                 w->rchild->color = true;
  148.                 Left_Rotate(x->parent);
  149.                 x = root;
  150.             }
  151.         }else{
  152.             struct RB_tree_node *w = x->parent->lchild;
  153.             if( w->color == false){
  154.                 w->color = true;
  155.                 x->parent->color = false;
  156.                 Right_Rotate(x->parent);
  157.                 w = x->parent->lchild;
  158.             }
  159.             if( w->lchild->color==true && w->rchild->color == true){
  160.                 w->color = false;x = x->parent;
  161.             }else{
  162.                 if(w->lchild->color == true){
  163.                     w->rchild->color = true;
  164.                     w->color = false;
  165.                     Left_Rotate(w);
  166.                     w = x->parent->lchild;
  167.                 }
  168.                 w->color = x->parent->color;
  169.                 x->parent->color = true;
  170.                 w->lchild->color = true;
  171.                 Right_Rotate(x->parent);
  172.                 x = root;
  173.             }
  174.         }
  175.     }
  176.     x->color = true;
  177. }
  178. struct RB_tree_node *Delet_Black_leaf(struct RB_tree_node *s){
  179.     if(s == s->parent->rchild){
  180.         if( s->color == false){
  181.             s->color = true;
  182.             s->parent->color = false;
  183.             Left_Rotate(s->parent);
  184.             s = s->lchild->rchild;
  185.         }
  186.         if( s->lchild==NULL && s->rchild== NULL ){
  187.             s->color = false;
  188.             return s->parent;
  189.         }else{
  190.             if(s->rchild == NULL){
  191.                 s->lchild->color = true;
  192.                 s->color = false;
  193.                 Right_Rotate(s);
  194.                 s = s->parent;
  195.             }
  196.             s->color = s->parent->color;
  197.             s->parent->color = true;
  198.             s->rchild->color = true;
  199.             Left_Rotate(s->parent);
  200.             return NULL;
  201.         }
  202.     }else{
  203.         if( s->color == false){
  204.             s->color = true;
  205.             s->parent->color = false;
  206.             Right_Rotate(s->parent);
  207.             s = s->rchild->lchild;
  208.         }
  209.         if( s->lchild==NULL && s->rchild== NULL ){
  210.             s->color = false;
  211.             return s->parent;
  212.         }else{
  213.             if(s->lchild == NULL){
  214.                 s->rchild->color = true;
  215.                 s->color = false;
  216.                 Left_Rotate(s);
  217.                 s = s->parent;
  218.             }
  219.             s->color = s->parent->color;
  220.             s->parent->color = true;
  221.             s->rchild->color = true;
  222.             Right_Rotate(s->parent);
  223.             return NULL;
  224.         }
  225.     }
  226. }
  227. void Delete(int val){
  228.     struct RB_tree_node *cur = Find(val);
  229.     if(!cur) return;
  230.     struct RB_tree_node *y = cur, *successor, *sibling;
  231.     bool original_color = y->color;
  232.     if( cur->lchild == NULL) {
  233.         successor = cur->rchild;
  234.         sibling = Get_Sibling(y);
  235.         Transplant(cur, cur->rchild);
  236.     }
  237.     else if( cur->rchild == NULL){
  238.         successor = cur->lchild;
  239.         sibling = Get_Sibling(y);
  240.         Transplant(cur, cur->lchild);
  241.     }
  242.     else{
  243.         y = cur->rchild;
  244.         while(y->lchild){
  245.             y = y->lchild;
  246.         }
  247.         original_color = y->color;
  248.         successor = y->rchild;
  249.         sibling = Get_Sibling(y);
  250.         cur->val = y->val;
  251.         Transplant(y, y->rchild);
  252.     }
  253.     if(original_color){
  254.         if(successor == NULL){
  255.             successor = Delet_Black_leaf(sibling);
  256.         }
  257.         if( successor)
  258.             Delete_fix(successor);
  259.     }
  260.     delete cur;
  261. }
  262. int main()
  263. {
  264.     int arr[] = {10, 7, 8, 15,5, 6,11, 13, 12 };//9
  265.     for(int i = 0; i < 9; i++){
  266.         insert(arr[i]);
  267.     }
  268.     Delete(15);
  269.     Delete(12);
  270.     Delete(10);
  271.     Delete(6);
  272.     Delete(8);
  273.     return 0;
  274. }
由于我没有采用算法导论当中的指定T.nil 来充当辅助节点,所以我在处理删除黑色叶子结点的时候,多谢了一个函数,其形式是照搬的Delete_fix函数~
阅读(2224) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~