• 红黑树学习笔记(3)-删除操作


    1、设删除的节点为$z$,另外定义节点$x,y$如下:

    $y=left{egin{matrix}z & z的左孩子或右孩子为空节点\ Successor(z) & otherwiseend{matrix} ight.$

    $x=left{egin{matrix}y.left & y的左孩子不为空\ y.right & otherwiseend{matrix} ight.$

    其中$Successor$函数的定义在这里

     接下来,用$x$替换节点$y$,所谓的替换就是$x$的父节点指向$y$的父节点,如果$y$是其父节点的左孩子,那么就让$y$的父节点的左孩子指向$x$,否则让$y$的父节点的右孩子指向$x$。然后令$z节点的值=y节点的值$.这样操作之后,实际上就是删掉了$z$节点。那么现在看节点$y$,其实是删掉了$z$节点的值和$y$节点的颜色,所以如果$y$节点的颜色是红色,那么本次删除操作就结束了,因为树的所有性质没有被破坏。相反如果$y$ 是黑色的,那么经过节点$x$的路径将会比不经过$x$的路径的黑色节点数少1。这种情况会修复节点$x$。下面是这个修复的过程。

    2 首先假设$x$是其父节点的左孩子($x$是其父节点的右孩子的情况跟这个完全类似)。整个修复过程有四种情况。在修复的过程中,这四种情况之间的转换关系如下图所示:

    也就是,如果是情况1,将会把情况1转换为情况2或者情况3、4,如果是情况3则会将其转换成情况4。

    设$w$是$x$的兄弟节点。另外,在所有的情况中,满足这样的条件,就是经过节点$x$的路径将会比不经过$x$的路径的黑色节点数少1。

    情况1: $w$的颜色为红色。这时候$x$父节点的颜色一定为黑色。如下图所示。首先将置$x$的父节点色颜色为红色,置$w$的颜色为黑色,然后左旋$x$的父节点,并重新令$w=x的兄弟节点$。这样,情况1将会转换为情况2或者情况3,4,也就是说情况2、3、4的$w$节点都是黑色。

    情况2:$w$是黑色,$w$的两个孩子都是黑色。注意这时候$x$的父节点的颜色可能是红色也可能是黑色,下图是红色的情况,但是这两种情况执行的操作都是一样的。这时将$w$的颜色置为红色,然后令$x=x的父节点$。

    情况3:$w$是黑色,$w$的右孩子是黑色(此时$w$的左孩子一定是红色,否则就是情况2了)。注意这时候$x$的父节点的颜色可能是红色也可能是黑色,下图是红色的情况,但是这两种情况执行的操作都是一样的。如下图所示。这种情况操作之后,将把$w$的右孩子转成红色节点,这也是情况4.现在交换$w$与其左孩子的颜色,然后右旋$w$,最后令$w=x现在的兄弟$

    情况4:$w$是黑色,$w$的右孩子是红色。注意这时候$x$的父节点的颜色可能是红色也可能是黑色,下图是红色的情况,但是这两种情况执行的操作都是一样的。首先交换$w$与其父节点的颜色,然后置$w$的右孩子为黑色,最后左旋$x$的父节点。这一步之后可结束整个修复过程。

      1 class RedBlackTree
      2 {
      3 private:
      4     static const int BLACK=1;
      5     static const int RED=0;
      6 
      7     struct TreeNode
      8     {
      9         int key;
     10         int color;
     11         TreeNode* p;
     12         TreeNode* left;
     13         TreeNode* right;
     14     };
     15 
     16     TreeNode* nullNode;
     17     TreeNode* root;
     18 
     19     TreeNode* NewNode(int val=0)
     20     {
     21 
     22         TreeNode* p=new TreeNode;
     23         p->p=p->left=p->right=nullNode;
     24         p->key=val;
     25 
     26         return p;
     27     }
     28 
     29 
     30 
     31     void leftRotate(TreeNode* x)
     32     {
     33         TreeNode* y=x->right;
     34         x->right=y->left;
     35         if(y->left!=nullNode) y->left->p=x;
     36         y->p=x->p;
     37         if(x->p==nullNode) root=y;
     38         else if(x==x->p->left) x->p->left=y;
     39         else x->p->right=y;
     40         y->left=x;
     41         x->p=y;
     42     }
     43 
     44     void rightRotate(TreeNode* x)
     45     {
     46         TreeNode* y=x->left;
     47         x->left=y->right;
     48         if(y->right!=nullNode) y->right->p=x;
     49         y->p=x->p;
     50         if(x->p==nullNode) root=y;
     51         else if(x==x->p->left) x->p->left=y;
     52         else x->p->right=y;
     53         y->right=x;
     54         x->p=y;
     55     }
     56 
     57 
     58     void transPlant(TreeNode* u,TreeNode*v)
     59     {
     60         if(u->p==nullNode) root=v;
     61         else if(u==u->p->left) u->p->left=v;
     62         else u->p->right=v;
     63         v->p=u->p;
     64     }
     65 
     66     TreeNode* minimum(TreeNode* x)
     67     {
     68         while(x->left!=nullNode) x=x->left;
     69         return x;
     70     }
     71 
     72     TreeNode* successor(TreeNode* x)
     73     {
     74         if(x->right!=nullNode) return minimum(x->right);
     75         TreeNode* px=x->p;
     76         while(px!=nullNode&&px->right==x)
     77         {
     78             x=px;
     79             px=px->p;
     80         }
     81         return px;
     82     }
     83 
     84 
     85 
     86     void insertFix(TreeNode* z)
     87     {
     88         while(z->p->color==RED)
     89         {
     90             if(z->p==z->p->p->left)
     91             {
     92                 TreeNode* y=z->p->p->right;
     93                 if(y->color==RED)
     94                 {
     95                     z->p->color=BLACK;
     96                     y->color=BLACK;
     97                     z->p->p->color=RED;
     98                     z=z->p->p;
     99                 }
    100                 else
    101                 {
    102                     if(z==z->p->right)
    103                     {
    104                         z=z->p;
    105                         leftRotate(z);
    106                     }
    107                     z->p->color=BLACK;
    108                     z->p->p->color=RED;
    109                     rightRotate(z->p->p);
    110                 }
    111             }
    112             else
    113             {
    114                 TreeNode* y=z->p->p->left;
    115                 if(y->color==RED)
    116                 {
    117                     z->p->color=BLACK;
    118                     y->color=BLACK;
    119                     z->p->p->color=RED;
    120                     z=z->p->p;
    121                 }
    122                 else
    123                 {
    124                     if(z==z->p->left)
    125                     {
    126                         z=z->p;
    127                         rightRotate(z);
    128                     }
    129                     z->p->color=BLACK;
    130                     z->p->p->color=RED;
    131                     leftRotate(z->p->p);
    132                 }
    133             }
    134         }
    135         root->color=BLACK;
    136     }
    137 
    138     TreeNode* FindNode(int val)
    139     {
    140         TreeNode* cur=root;
    141         while(cur!=nullNode)
    142         {
    143             if(cur->key==val) return cur;
    144             if(cur->key>val) cur=cur->left;
    145             else cur=cur->right;
    146         }
    147         return cur;
    148     }
    149 
    150     void removeFix(TreeNode* x)
    151     {
    152         while(x!=root&&x->color==BLACK)
    153         {
    154             if(x==x->p->left)
    155             {
    156                 TreeNode* w=x->p->right;
    157                 if(w->color==RED)
    158                 {
    159                     w->color=BLACK;
    160                     x->p->color=RED;
    161                     leftRotate(x->p);
    162                     w=x->p->right;
    163                 }
    164                 if(w->left->color==BLACK&&w->right->color==BLACK)
    165                 {
    166                     w->color=RED;
    167                     x=x->p;
    168                 }
    169                 else
    170                 {
    171                     if(w->right->color==BLACK)
    172                     {
    173                         w->left->color=BLACK;
    174                         w->color=RED;
    175                         rightRotate(w);
    176                         w=x->p->right;
    177                     }
    178                     w->color=x->p->color;
    179                     x->p->color=BLACK;
    180                     w->right->color=BLACK;
    181                     leftRotate(x->p);
    182                     x=root;
    183                 }
    184             }
    185             else
    186             {
    187                 TreeNode* w=x->p->left;
    188                 if(w->color==RED)
    189                 {
    190                     w->color=BLACK;
    191                     x->p->color=RED;
    192                     rightRotate(x->p);
    193                     w=x->p->left;
    194                 }
    195                 if(w->left->color==BLACK&&w->right->color==BLACK)
    196                 {
    197                     w->color=RED;
    198                     x=x->p;
    199                 }
    200                 else
    201                 {
    202                     if(w->left->color==BLACK)
    203                     {
    204                         w->right->color=BLACK;
    205                         w->color=RED;
    206                         leftRotate(w);
    207                         w=x->p->left;
    208                     }
    209                     w->color=x->p->color;
    210                     x->p->color=BLACK;
    211                     w->left->color=BLACK;
    212                     rightRotate(x->p);
    213                     x=root;
    214                 }
    215             }
    216         }
    217         x->color=BLACK;
    218     }
    219 
    220 
    221 public:
    222 
    223     RedBlackTree() { init(); }
    224 
    225     void init()
    226     {
    227         nullNode=new TreeNode;
    228         nullNode->left=nullNode->right=nullNode->p=nullNode;
    229         nullNode->color=BLACK;
    230 
    231         root=nullNode;
    232     }
    233 
    234     void insert(int val)
    235     {
    236         TreeNode* z=NewNode(val);
    237 
    238         TreeNode* y=nullNode;
    239         TreeNode* x=root;
    240         while(x!=nullNode)
    241         {
    242             y=x;
    243             if(z->key<x->key) x=x->left;
    244             else x=x->right;
    245         }
    246         z->p=y;
    247         if(y==nullNode) root=z;
    248         else if(z->key<y->key) y->left=z;
    249         else y->right=z;
    250         z->color=RED;
    251 
    252         insertFix(z);
    253     }
    254 
    255 
    256     void remove(int val)
    257     {
    258         TreeNode* z=FindNode(val);
    259         if(z==nullNode) return;
    260         TreeNode* y;
    261         TreeNode* x;
    262 
    263         if(z->left==nullNode||z->right==nullNode) y=z;
    264         else y=successor(z);
    265 
    266         if(y->left!=nullNode) x=y->left;
    267         else x=y->right;
    268 
    269         transPlant(y,x);
    270 
    271         if(y!=z) z->key=y->key;
    272 
    273         if(y->color==BLACK) removeFix(x);
    274         delete y;
    275     }
    276 
    277 };
  • 相关阅读:
    window10-jmeter安装
    软件开发模型
    软件测试的原则和流程
    手机APP测试
    优秀的软件测试工程师
    自动化测试
    测试用例
    软件测试功能分类
    ios-prefix文件最全
    催收策略及催收评分卡搭建
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/6011696.html
Copyright © 2020-2023  润新知