数据结构备忘录:红黑树的插入与删除

Posted wskit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构备忘录:红黑树的插入与删除相关的知识,希望对你有一定的参考价值。

红黑树的删除

红黑树删除极其复杂,实现难度比AVL树删除更大,要考虑的各种分支情况繁多,编程实现时在琐碎的细节上容易出错,但只要用心,正确实现删除算法不难

对红黑树按对二叉搜索树执行删除的方式执行删除,如果实际删除的节点是红节点,按正常方式删除,删除后原树仍为红黑树,结束

若实际删除的是黑节点,该节点有父节点并且有唯一子女节点且该子女节点为红,将该子女节点染黑,并按对二叉搜索树执行删除的方式删掉实际删除的节点即可,结束

若实际删除黑节点,该节点有父节点,没有子女节点,直接删除实际删除节点,将父节点对应指针域置空,令g=父节点,u=nullptr

若实际删除黑节点,该节点有父节点,有唯一女节点,该子女节点为黑,则按对二叉搜索树执行删除的方式正常执行删除,并令g=实际删除节点父节点  u=实际删除节点子女节点

若实际删除黑节点,该节点没有父节点,若该节点没有子树直接删除啦,若该节点有左子树没有右子树,删除该黑节点,然后若左子树根节点为红染黑,结束  无左子树有右子树类似

至于既有左子树又有右子树的情形已经被之前所述情形包括在内了,不用考虑

经过上述步骤后如果删除操作未结束,我们有子树g,g为其根节点,u为g左子树或右子树根节点,注意u可能为nullptr,即外节点

而且可以发现u子树满足条件A:在u中删除一个节点,并在u中做或不做颜色调整和平衡化旋转后,根节点u为黑色,从原红黑树根节点到子树u各外节点的路径上黑色节点(不包括原红黑树根节点)数目比删除前原红黑树黑高度小一,从根节点u至子树u各外节点的路径上没有两个连续的红色节点,子树u为二叉搜索树,子树u的节点非红即黑

现设有执行删除操作的红黑树的子树g,g为其根节点,以u为根节点的子树为g左子树或右子树,u可以为nullptr,并且u子树满足条件A

首先注意,任意非外节点的节点都有两个子女,两个子女要么都是外节点,要么其中一个是,要么都不是,当然了红色节点都不是外节点所以必有两个子女,黑色节点可能为也可能不为外节点

若u为g的右子女,则有以下几种情形:

 

技术分享图片

g的左子女v为黑色,g为红色,此时v不可能是外节点,若v是外节点,注意原红黑树根节点到外节点v的路径上黑色节点(不包括原红黑树根节点)数目等于删除前原红黑树黑高度r,而原红黑树根节点到子树u的各外节点的路径上黑色节点(不包括原红黑树根节点)数目等于r-1(子树u满足条件A),因此g到v路径(节点g不算在内)上黑色节点数目减一即为g到子树u各外节点的路径(节点g不算在内)上黑色节点数目,由假设v是外节点,故g到v路径(节点g不算在内)上黑色节点数目为1,因此g到子树u各外节点的路径(节点g不算在内)上黑色节点数目为0,这是不可能的,因为u为黑色

v不是外节点所以有左子女w,这里若w为红色,即如上图所示,此时交换g,w和v的颜色,对子树g右单旋转,然后根据子树u满足条件A不难验证此时原树为红黑树已平衡,结束

 技术分享图片

g的左子女v为黑色,g为红色,v的左子女w为黑色,v的有子女r为红色,对g先左后右双旋转,将g染黑,然后根据子树u满足条件A不难验证此时原树为红黑树已平衡,结束

技术分享图片

g的左子女v为黑色,g为红色,v的左子女w为黑色,v的有子女r为黑色,此时交换g,v颜色,然后根据子树u满足条件A不难验证此时原树为红黑树已平衡,结束

技术分享图片

g的左子女v为黑色,g为黑色,v(由上述理由它不是外节点)的左子女w为红色,此时对g右单旋转然后将w染黑,然后根据子树u满足条件A不难验证此时原树为红黑树已平衡,结束

技术分享图片

g的左子女v为黑色,g为黑色,v的左子女w为黑色,v的右子女r为红色,此时对g做先左后右双旋转然后将r染黑,然后根据子树u满足条件A不难验证此时原树为红黑树已平衡,结束

 技术分享图片

 

g的左子女v为黑色,g为黑色,v的左子女w为黑色,v的右子女r为黑色,此时对g作右单旋转,并将g染红色,于是根据子树u满足条件A不难验证g树旋转后为红黑树而且恰好满足条件A,那么若旋转后的g树的根已为执行删除操作的红黑树根节点则可以结束平衡化过程,若不为根节点,由于旋转后的g树满足条件A,所以原红黑树仍然不平衡,于是令u=旋转后g树根节点  g=旋转前g树根节点父节点,回溯至上一层按所列各情形执行平衡化,这样做是合理的,因为旋转后的g树满足条件A。

 技术分享图片

g的左子女v为红色,g为黑色,v的右子女r为黑色(显然),按和上述同样的理由r不可能是外节点,所以r必有左子女s,若s为红色,则对g做先左后右双旋转,将s染黑,然后根据子树u满足条件A不难验证此时原树为红黑树已平衡,结束

技术分享图片

 

g的左子女v为红色,g为黑色,v的右子女r为黑色,r的左子女s为黑色,r的右子女t为红色,此时对子树r做左单旋转,旋转完后将其根节点链接至v的右指针域,然后对子树g做先左后右双旋转并把t染成黑色,然后根据子树u满足条件A不难验证此时原树为红黑树已平衡,结束

 技术分享图片

g的左子女v为红色,g为黑色,v的右子女r为黑色,r的左子女s为黑色,r的右子女t为黑色,此时对子树g做右单旋转并交换v和r的颜色,然后根据子树u满足条件A不难验证此时原树为红黑树已平衡,结束

 若u为g的右子女,则有如下几种情形,这些情形和u为g的右子女时对应的情形是对称的,以下所列这些情形从上之下依次和上文所列各情形从上至下保持对应的对称关系,平衡化操作和颜色调整操作也保持对应,颜色调整操作不便,平衡化操作正好相反,分析是类似,就不一一分析,只简单地列出平衡化操作的类型和颜色调整操作。

技术分享图片

 

g左单旋转,交换w,g和v颜色,结束

 

技术分享图片

g先右后左双旋转,g染黑,结束

 

技术分享图片

交换g,v颜色,结束

 

技术分享图片

g左单旋转,w染黑,结束

 

技术分享图片

g先右后左双旋转,r染黑,结束

 

技术分享图片

g左单旋转,g染红,若旋转后的g树的根已为执行删除操作的红黑树根节点,结束,否则令u=旋转后g树根节点  g=旋转前g树根节点父节点,回溯至上一层按所列各情形执行平衡化

 

 技术分享图片

g先右后左双旋转,s染黑,结束

 

技术分享图片

r右单旋转,g先右后左双旋转,t染黑结束

 

技术分享图片

g左单旋转,改变u和r的颜色,结束

 

从以上讨论就可以看出循环不变量了,它就是u子树满足的条件A,利用该循环不变量结合前面的介绍和博主所写的AVL树插入删除算法分析一文中的分析思路就可总结出红黑树的删除算法,这里省略,可自行分析。红黑树删除算法的具体实现请参考下方代码。

下面讨论红黑树的插入

在空树中插入可直接插入,再把插入节点染黑,如果在非空红黑树中插入,设插入的新节点为u,u在节点p下插入,那么无论u是在p的左子树还是右子树中插入,以u为根的子树(左右子树为外节点)总满足以下条件B 

按对二叉搜索树执行插入的方式在子树u中插入新节点后,在u中做或不做颜色调整及平衡化旋转后,子树u根节点u为红色,从执行插入操作的红黑树根节点至子树u各外节点的路径上黑色节点(不包括该红黑树根节点)的数目都等于插入前原红黑树的黑高度

u至子树u任意外节点的路径上没有两个连续的红色节点,子树u为二叉搜索树,子树u所有节点非红即黑。

先设有执行插入操作的红黑树的子树u,它满足条件B,u的父节点为p,u为p的左子女或右子女。

 

若u为p的左子女,则有如下几种情形:

技术分享图片

p为黑色,此时由子树u满足条件B不难验证执行插入操作的红黑树已恢复平衡,结束平衡化过程

技术分享图片

 

p为红色,由原红黑树的特性知p有父节点g,p为g的左子女,g为黑色,若g的右子女r为红色,则交换g和p,r的颜色,若g已为执行插入操作的红黑树的根节点,则将g染黑,此时由子树u满足条件B不难验证子树g为红黑树,于是结束平衡化过程 。若g不为执行插入操作的红黑树的根节点,由子树u满足条件B不难验证此时子树g满足条件B,但g的颜色由黑变红意味着g和其父节点有可能组成一对连续红节点,所以此时应令u=g    p=g的父节点,回溯至上一层按所列各情形进行相同的平衡化处理,以消除可能出现的一对连续红色节点,这样做是合理的,因为交换颜色后的子树g满足条件B。

技术分享图片

p为红色,由原红黑树的特性知p有父节点g,p为g的右子女,g为黑色,若g的左子女r为红色,则对g先右后左双旋转并把p染成黑色,和上一情形类似,若g已为执行插入操作的红黑树的根节点,则将g染黑,结束。若g不为执行插入操作的红黑树的根节点,则令u=g    p=g的父节点,回溯至上一层按所列各情形进行相同的平衡化处理

技术分享图片

p为红色,由原红黑树的特性知p有父节点g,p为g的左子女,g为黑色,g的右子女r为黑色,此时g做右单旋转并交换p,g颜色,然后由子树u满足条件B不难验证此时执行插入操作的红黑树已恢复红黑树特性,结束平衡化过程。

技术分享图片

p为红色,p有父节点g,p为g的右子女,g为黑色,g的左子女r为黑色,此时对g先右后左双旋转并交换v,g颜色,然后由子树u满足条件B不难验证此时执行插入操作的红黑树已恢复红黑树特性,结束平衡化过程。

 

若u为p的右子女,也有类似诸情形,这些情形和以上对应各情形保持对称,每一种情形和其对应的以上情形相比,颜色调整操作不便,旋转操作互为镜像,下面将这些情形及相应的处理方式列出,这些情形从上至下和上述情形从上至下保持对应和对称

 技术分享图片

p为黑色,已平衡,结束

技术分享图片

 

p为红色,由原红黑树的特性知p有父节点g,p为g的右子女,g为黑色,若g的左子女r为红色则交换g和p,r颜色,若g已为执行插入操作的红黑树的根节点,则将g染黑,结束平衡化过程 。若g不为执行插入操作的红黑树的根节点,令u=g    p=g的父节点,回溯至上一层按所列各情形进行相同的平衡化处理

技术分享图片

p为红色,由原红黑树的特性知p有父节点g,p为g的左子女,g为黑色,若g的右子女r为红色,则对g先左后右双旋转并把p染成黑色,然后若g已为执行插入操作的红黑树的根节点,则将g染黑,结束。若g不为执行插入操作的红黑树的根节点,则令u=g    p=g的父节点,回溯至上一层按所列各情形进行相同的平衡化处理

技术分享图片

p为红色,由原红黑树的特性知p有父节点g,p为g的右子女,g为黑色,g的左子女r为黑色,此时g做左单旋转并交换p,g颜色,然后已平衡,结束平衡化过程。

技术分享图片

p为红色,p有父节点g,p为g的左子女,g为黑色,g的右子女r为黑色,此时对g先左后右双旋转并交换v,g颜色,然后结束平衡化过程。

 

从以上讨论就可以看出循环不变量就是u子树满足的条件B,由此可总结出红黑树的插入算法,这里省略,可自行分析。红黑树插入算法的具体实现请参考下方代码。

下面是实现红黑树插入与删除操作的具体代码(c++),代码中加入了判断节点颜色非红即黑的二叉树是否为红黑树的函数,用其在每次插入删除成功后检验插入删除后的二叉树是否仍为红黑树以判断插入删除算法的正确性

   1 #include "stdafx.h"
   2 #include <string>
   3 #include <vector>
   4 #include <iostream>
   5 #include <stack>
   6 using namespace std;
   7 
   8 #define TYPE int
   9 enum ColorFlag {RED, BLACK};
  10 
  11 template <typename T>
  12 struct RBTreeNode
  13 {
  14     T data;   //节点数据域
  15     ColorFlag color;  //节点颜色
  16     RBTreeNode *left;
  17     RBTreeNode *right;
  18     RBTreeNode(T d, ColorFlag c) :data(d), color(c), left(nullptr), right(nullptr) {}
  19 };
  20 
  21 template <typename T>
  22 void RotateLR(RBTreeNode<T> *&ptr)  //对以ptr为根的子树执行先左后右双旋转,ptr成为旋转后新树根节点指针
  23 {
  24     RBTreeNode<T> *p = ptr->left;
  25     RBTreeNode<T> *q = p->right;
  26     p->right = q->left;
  27     q->left = p;
  28     ptr->left = q->right;
  29     q->right = ptr;
  30     ptr = q;
  31 }
  32 
  33 template <typename T>
  34 void RotateRL(RBTreeNode<T> *&ptr)  //对以ptr为根的子树执行先右后左双旋转,ptr成为旋转后新树根节点指针
  35 {
  36     RBTreeNode<T> *p = ptr->right;
  37     RBTreeNode<T> *q = p->left;
  38     p->left = q->right;
  39     q->right = p;
  40     ptr->right = q->left;
  41     q->left = ptr;
  42     ptr = q;
  43 }
  44 
  45 template <typename T>
  46 void RotateR(RBTreeNode<T> *&ptr)  //对以ptr为根的子树执行右单旋转,ptr成为旋转后新树根节点指针
  47 {
  48     RBTreeNode<T> *p = ptr->left;
  49     ptr->left = p->right;
  50     p->right = ptr;
  51     ptr = p;
  52 }
  53 
  54 template <typename T>
  55 void RotateL(RBTreeNode<T> *&ptr)  ////对以ptr为根的子树执行左单旋转,ptr成为旋转后新树根节点指针
  56 {
  57     RBTreeNode<T> *p = ptr->right;
  58     ptr->right = p->left;
  59     p->left = ptr;
  60     ptr = p;
  61 }
  62 
  63 template <typename T>
  64 bool isRB(RBTreeNode<T> *root)  //判断以root为根的二叉树是否为红黑树(已假定节点颜色不是为红色就是为黑色)
  65 {
  66     if (root->color == ColorFlag::RED)
  67     {
  68         cout << "根节点不为黑色,非红黑树" << endl;
  69         return false;
  70     }
  71         
  72     struct temp
  73     {
  74         T lmin;
  75         T lmax;
  76         T rmin;
  77         T rmax;
  78     };
  79     struct memory
  80     {
  81         RBTreeNode<T> *p;
  82         int direction;
  83         temp minmax;
  84         memory(RBTreeNode<T> *p, int d) :p(p), direction(d) {}
  85     };
  86     int d = 0;
  87     RBTreeNode<T> *ptr = root;
  88     RBTreeNode<T> *const dest = ptr;
  89     stack<memory> arrange;
  90     bool TF = false;
  91     int blacknum = 0;  //统计路径上黑节点个数的变量
  92     int preroadblacknum = 0;  //当前路径的前一路径上黑节点数目
  93     while (true)
  94     {
  95         if (Searchd(ptr, d) == 0)
  96         {
  97             if (ptr == dest)
  98             {
  99                 if (d == 0)
 100                     return true;
 101                 else
 102                 {
 103                     if (ptr->left == nullptr || ptr->right != nullptr)
 104                     {
 105                         if (ptr->data < arrange.top().minmax.rmin)
 106                         {
 107                             arrange.pop();
 108                         }
 109                         else
 110                         {
 111                             cout << "当前树非二叉搜索树,也非红黑树" << endl;
 112                             return false;
 113                         }
 114                     }
 115                     else
 116                     {
 117                         if (ptr->data > arrange.top().minmax.lmax)
 118                         {
 119                             arrange.pop();
 120                         }
 121                         else
 122                         {
 123                             cout << "当前树非二叉搜索树,也非红黑树" << endl;
 124                             return false;
 125                         }
 126                     }
 127                     return true;
 128                 }
 129             }
 130             else
 131             {
 132                 if (d == 0)
 133                 {
 134                     if (ptr->color == ColorFlag::BLACK)
 135                         ++blacknum;
 136                     if (TF == false)
 137                     {
 138                         TF = true;
 139                         preroadblacknum = blacknum;
 140                     }
 141                     else
 142                     {
 143                         if (preroadblacknum != blacknum)
 144                         {
 145                             cout << "从根节点到外节点的路径上黑节点数目不等,非红黑树" << endl;
 146                             return false;
 147                         }
 148                         else
 149                         {
 150                             preroadblacknum = blacknum;
 151                         }
 152                     }
 153 
 154                     if (arrange.top().direction == 1)
 155                     {
 156                         arrange.top().minmax.lmin = ptr->data;
 157                         arrange.top().minmax.lmax = ptr->data;
 158                     }
 159                     else
 160                     {
 161                         arrange.top().minmax.rmin = ptr->data;
 162                         arrange.top().minmax.rmax = ptr->data;
 163                     }
 164                 }
 165                 else
 166                 {
 167                     if (ptr->left == nullptr || ptr->right != nullptr)
 168                     {
 169                         if (ptr->data < arrange.top().minmax.rmin)
 170                         {
 171                             temp temp1 = arrange.top().minmax;
 172                             arrange.pop();
 173                             if (arrange.top().direction == 1)
 174                             {
 175                                 if (ptr->left == nullptr)
 176                                 {
 177                                     arrange.top().minmax.lmin = ptr->data;
 178                                 }
 179                                 else
 180                                 {
 181                                     arrange.top().minmax.lmin = temp1.lmin;
 182                                 }
 183                                 arrange.top().minmax.lmax = temp1.rmax;
 184                             }
 185                             else
 186                             {
 187                                 if (ptr->left == nullptr)
 188                                 {
 189                                     arrange.top().minmax.rmin = ptr->data;
 190                                 }
 191                                 else
 192                                 {
 193                                     arrange.top().minmax.rmin = temp1.lmin;
 194                                 }
 195                                 arrange.top().minmax.rmax = temp1.rmax;
 196                             }
 197                         }
 198                         else
 199                         {
 200                             cout << "当前树非二叉搜索树,也非红黑树" << endl;
 201                             return false;
 202                         }
 203                     }
 204                     else
 205                     {
 206                         if (ptr->data > arrange.top().minmax.lmax)
 207                         {
 208                             temp temp1 = arrange.top().minmax;
 209                             arrange.pop();
 210                             if (arrange.top().direction == 1)
 211                             {
 212                                 arrange.top().minmax.lmin = temp1.lmin;
 213                                 arrange.top().minmax.lmax = ptr->data;
 214                             }
 215                             else
 216                             {
 217                                 arrange.top().minmax.rmin = temp1.lmin;
 218                                 arrange.top().minmax.rmax = ptr->data;
 219                             }
 220                         }
 221                         else
 222                         {
 223                             cout << "当前树非二叉搜索树,也非红黑树" << endl;
 224                             return false;
 225                         }
 226                     }
 227                 }
 228                 if (ptr->color == ColorFlag::BLACK)
 229                     --blacknum;
 230                 ptr = arrange.top().p;
 231                 d = arrange.top().direction;
 232             }
 233         }
 234         else
 235         {
 236             RBTreeNode<T> *interval = nullptr;
 237             if (d == 0)
 238             {
 239                 if (arrange.empty() == false && arrange.top().p != dest)
 240                 {
 241                     if (ptr->color == ColorFlag::RED && arrange.top().p->color == ColorFlag::RED)
 242                     {
 243                         cout << "在根节点到父节点的路径上存在两个连续红色节点,非红黑树" << endl;
 244                         return false;
 245                     }
 246                 }
 247                 if (ptr->color == ColorFlag::BLACK)
 248                     ++blacknum;
 249                 arrange.push(memory(ptr, Searchd(ptr, d)));
 250                 if (arrange.top().direction == 1)
 251                     interval = ptr->left;
 252                 else
 253                     interval = ptr->right;
 254             }
 255             else
 256             {
 257                 if (!(ptr->data > arrange.top().minmax.lmax))
 258                 {
 259                     cout << "当前树非二叉搜索树,也非红黑树" << endl;
 260                     return false;
 261                 }
 262                 arrange.top().direction = 2;
 263                 interval = ptr->right;
 264             }
 265             d = 0;
 266             ptr = interval;
 267         }
 268     }
 269 }
 270 
 271 template <typename T>
 272 RBTreeNode<T> *DelRB(RBTreeNode<T> *root, T key)
 273 {
 274     //红黑树删除
 275     RBTreeNode<T> *p = root;
 276     stack<RBTreeNode<T> *> stackforflashback;
 277     while (p != nullptr)         //搜索被删除节点,同时将回溯路径记录在栈中
 278     {
 279         if (p->data == key)
 280             break;
 281         else
 282         {
 283             stackforflashback.push(p);
 284             if (key < p->data)
 285             {
 286                 p = p->left;
 287             }
 288             else
 289             {
 290                 p = p->right;
 291             }
 292         }
 293     }
 294 
 295     if (p != nullptr)  //被删除节点存在,被p指向
 296     {
 297         RBTreeNode<T> *parent = nullptr;
 298         RBTreeNode<T> *q = nullptr;
 299         if (p->left != nullptr && p->right != nullptr)   //被删节点左右子树均存在
 300         {
 301             q = p->right;
 302             if (q->left != nullptr)   //被删节点右子树根节点有左子树
 303             {
 304                 parent = p;
 305                 stackforflashback.push(parent);
 306                 while (q->left != nullptr)  //在被删节点右子树根节点左子树中搜索中序遍历的第一个节点,同时用栈记录回溯路径
 307                 {
 308                     parent = q;
 309                     q = q->left;
 310                     if (q->left != nullptr)
 311                         stackforflashback.push(parent);
 312                 }
 313                 parent->left = q->right;  //用该节点数据域替换被删节点数据域,将其右子树链接至其父节点左链指针
 314                 p->data = q->data;
 315                 if (q->color == ColorFlag::RED)  //如果被删节点为红色,直接删除即可
 316                 {
 317                     delete q;
 318                     return root;     //已平衡返回根节点
 319                 }
 320                 else
 321                 {
 322                     if (q->right == nullptr)  //被删节点为叶子黑节点,直接删除,子树q满足循环不变条件,向下进入do-while循环
 323                     {
 324                         delete q;
 325                     }
 326                     else
 327                     {
 328                         if (q->right->color == ColorFlag::RED)  //被删节点右子树根节点为红色
 329                         {
 330                             q->right->color = ColorFlag::BLACK;   //右子树根节点染黑,删除被删节点,红黑树恢复平衡,结束
 331                             delete q;
 332                             return root;
 333                         }
 334                         else
 335                         {
 336                             delete q;   //被删节点及其右子女均为黑色,直接删除被删节点
 337                         }
 338                     }
 339                 }
 340                 q = parent->left; //parent为需要做或不做平衡化旋转及颜色调整的第一棵子树根节点指针,q为该子树左子树根节点指针
 341 
 342             }
 343             else
 344             {
 345                 p->right = q->right;   //用被删节点右子女数据域替换被删节点指针域,将右子女右子树链接至被删节点右链指针
 346                 p->data = q->data;
 347                 if (q->color == ColorFlag::RED)
 348                 {
 349                     delete q;
 350                     return root;
 351                 }
 352                 else
 353                 {
 354                     if (q->right == nullptr)
 355                     {
 356                         delete q;
 357                     }
 358                     else
 359                     {
 360                         if (q->right->color == ColorFlag::RED)
 361                         {
 362                             q->right->color = ColorFlag::BLACK;
 363                             delete q;
 364                             return root;
 365                         }
 366                         else
 367                         {
 368                             delete q;
 369                         }
 370                     }
 371                 }
 372                 parent = p;
 373                 q = p->right;  //parent为需要做或不做平衡化旋转的第一棵子树根节点指针,q为该子树左子树根节点指针
 374             }
 375         }
 376         else
 377         {
 378             if (p->left != nullptr)  //被删节点左子树不空,右子树空
 379             {
 380                 if (stackforflashback.empty() == false)  //被删节点有父节点
 381                 {
 382                     parent = stackforflashback.top();
 383                     stackforflashback.pop();
 384                     if (parent->left == p)
 385                     {
 386                         parent->left = p->left;
 387                         q = parent->left;
 388                     }                     //将被删节点左子树链接至被删节点父节点相应链指针
 389                     else
 390                     {
 391                         parent->right = p->left;
 392                         q = parent->right;
 393                     }                          
 394 
 395                     if (p->color == ColorFlag::RED)   //被删节点颜色为红,直接删除结束
 396                     {
 397                         delete p;
 398                         return root;
 399                     }
 400                     else
 401                     {
 402                         if (p->left->color == ColorFlag::RED)  //被删节点为黑但左子女为红,左子女染黑,删除被删节点,已平衡返回根节点
 403                         {
 404                             p->left->color = ColorFlag::BLACK;
 405                             delete p;
 406                             return root;
 407 
 408                         }
 409                         else
 410                         {
 411                             delete p;    //q为需要做或不做平衡化旋转和颜色调整的第一棵子树根节点指针,q子树满足循环不变条件,删除被删节点,进入do-while循环
 412                         }
 413                     }
 414                 }
 415                 else  //被删节点为根节点且只有左子树
 416                 {
 417                     parent = p->left;
 418                     delete p;     //直接删除被删节点,左子女若为红直接染黑,这样左子树为红黑树,结束    
 419                     if (parent->color == ColorFlag::RED)
 420                         parent->color = ColorFlag::BLACK;
 421                     return parent;
 422                 }
 423             }
 424             else if (p->right != nullptr)  //处理过程和以上情形完全对称
 425             {
 426                 if (stackforflashback.empty() == false)
 427                 {
 428                     parent = stackforflashback.top();
 429                     stackforflashback.pop();
 430                     if (parent->left == p)
 431                     {
 432                         parent->left = p->right;
 433                         q = parent->left;
 434                     }
 435                     else
 436                     {
 437                         parent->right = p->right;
 438                         q = parent->right;
 439                     }               
 440 
 441                     if (p->color == ColorFlag::RED)
 442                     {
 443                         delete p;
 444                         return root;
 445                     }
 446                     else
 447                     {
 448                         if (p->right->color == ColorFlag::RED)
 449                         {
 450                             p->right->color = ColorFlag::BLACK;
 451                             delete p;
 452                             return root;
 453 
 454                         }
 455                         else
 456                         {
 457                             delete p;
 458                         }
 459                     }
 460                 }
 461                 else
 462                 {
 463                     parent = p->right;
 464                     delete p;   
 465                     if (parent->color == ColorFlag::RED)
 466                         parent->color = ColorFlag::BLACK;
 467                     return parent;
 468                 }
 469             }
 470             else        //被删节点为叶节点
 471             {
 472                 if (stackforflashback.empty() == false)   //被删叶节点有父节点
 473                 {
 474                     parent = stackforflashback.top();
 475                     stackforflashback.pop();
 476                     if (parent->left == p)
 477                     {
 478                         parent->left = nullptr;
 479                         q = parent->left;
 480                     }
 481                     else                          //将叶节点的父节点对应指针域置空
 482                     {
 483                         parent->right = nullptr;
 484                         q = parent->right;
 485                     }                        //
 486                     if (p->color == ColorFlag::RED)  
 487                     {
 488                         delete p;
 489                         return root;
 490                     }
 491                     else   //被删叶节点为黑,直接删除,此时q为需要做或不做平衡化旋转和颜色调整的第一棵子树根节点指针,q子树满足循环不变条件,向下进入do-while循环
 492                     {
 493                         delete p;
 494                     }
 495                 }
 496                 else     //被删叶节点为根节点,直接删除,结束
 497                 {
 498                     parent = nullptr;
 499                     delete p;       
 500                     return parent;
 501                 }
 502             }
 503         }
 504         
 505         bool TF = false;
 506         do   //do-while循环所做工作是,从满足循环不变条件的第一棵子树起,沿父节点到第一棵子树根节点的路径向上平衡化旋转或调整颜色,直到原红黑树重新恢复平衡为止
 507         {
 508             if (TF == true)
 509                 stackforflashback.pop();
 510             else
 511                 TF = true;
 512 
 513             if (parent->right == q)
 514             {
 515                 if (parent->color == ColorFlag::RED)
 516                 {
 517                     p = parent->left;
 518                     if (p->left != nullptr && p->left->color == ColorFlag::RED)
 519                     {
 520                         q = parent;
 521                         parent->color = ColorFlag::BLACK;
 522                         p->color = ColorFlag::RED;
 523                         p->left->color = ColorFlag::BLACK;
 524                         RotateR(parent);
 525 
 526                         if (stackforflashback.empty() == false)
 527                         {
 528                             if (stackforflashback.top()->left == q)
 529                                 stackforflashback.top()->left = parent;
 530                             else
 531                                 stackforflashback.top()->right = parent;
 532                             return root;
 533                         }
 534                         else
 535                         {
 536                             parent->color = ColorFlag::BLACK;
 537                             return parent;
 538                         }
 539                     }
 540                     else
 541                     {
 542                         if (p->right != nullptr && p->right->color == ColorFlag::RED)
 543                         {
 544                             q = parent;
 545                             parent->color = ColorFlag::BLACK;
 546                             RotateLR(parent);
 547 
 548                             if (stackforflashback.empty() == false)
 549                             {
 550                                 if (stackforflashback.top()->left == q)
 551                                     stackforflashback.top()->left = parent;
 552                                 else
 553                                     stackforflashback.top()->right = parent;
 554                                 return root;
 555                             }
 556                             else
 557                             {
 558                                 parent->color = ColorFlag::BLACK;
 559                                 return parent;
 560                             }
 561                         }
 562                         else
 563                         {
 564                             parent->color = ColorFlag::BLACK;
 565                             p->color = ColorFlag::RED;
 566                             return root;
 567                         }
 568                     }
 569                 }
 570                 else
 571                 {
 572                     p = parent->left;
 573                     if (p->color == ColorFlag::BLACK)
 574                     {
 575                         if (p->left != nullptr && p->left->color == ColorFlag::RED)
 576                         {
 577                             q = parent;
 578                             p->left->color = ColorFlag::BLACK;
 579                             RotateR(parent);
 580 
 581                             if (stackforflashback.empty() == false)
 582                             {
 583                                 if (stackforflashback.top()->left == q)
 584                                     stackforflashback.top()->left = parent;
 585                                 else
 586                                     stackforflashback.top()->right = parent;
 587                                 return root;
 588                             }
 589                             else
 590                             {
 591                                 return parent;
 592                             }
 593                         }
 594                         else
 595                         {
 596                             if (p->right != nullptr && p->right->color == ColorFlag::RED)
 597                             {
 598                                 q = parent;
 599                                 p->right->color = ColorFlag::BLACK;
 600                                 RotateLR(parent);
 601 
 602                                 if (stackforflashback.empty() == false)
 603                                 {
 604                                     if (stackforflashback.top()->left == q)
 605                                         stackforflashback.top()->left = parent;
 606                                     else
 607                                         stackforflashback.top()->right = parent;
 608                                     return root;
 609                                 }
 610                                 else
 611                                 {
 612                                     return parent;
 613                                 }
 614                             }
 615                             else
 616                             {
 617                                 q = parent;
 618                                 parent->color = ColorFlag::RED;
 619                                 RotateR(parent);
 620                                 if (stackforflashback.empty() == false)
 621                                 {
 622                                     if (stackforflashback.top()->left == q)
 623                                         stackforflashback.top()->left = parent;
 624                                     else
 625                                         stackforflashback.top()->right = parent;
 626                                     q = parent;
 627                                     parent = stackforflashback.top();
 628                                 }
 629                             }
 630                         }
 631                     }
 632                     else
 633                     {
 634                         q = p->right;
 635                         if (q->left != nullptr && q->left->color == ColorFlag::RED)
 636                         {
 637                             q->left->color = ColorFlag::BLACK;
 638                             q = parent;  
 639                             RotateLR(parent);
 640                         }
 641                         else
 642                         {
 643                             if (q->right != nullptr && q->right->color == ColorFlag::RED)
 644                             {
 645                                 q->right->color = ColorFlag::BLACK;
 646                                 q = parent;
 647                                 RotateL(p->right);
 648                                 RotateLR(parent);
 649                             }
 650                             else
 651                             {
 652                                 p->color = ColorFlag::BLACK;
 653                                 q->color = ColorFlag::RED;
 654                                 q = parent;  
 655                                 RotateR(parent);
 656                             }
 657                         }
 658 
 659                         if (stackforflashback.empty() == false)
 660                         {
 661                             if (stackforflashback.top()->left == q)
 662                                 stackforflashback.top()->left = parent;
 663                             else
 664                                 stackforflashback.top()->right = parent;
 665                             return root;
 666                         }
 667                         else
 668                         {
 669                             return parent;
 670                         }
 671                     }
 672                 }
 673             }
 674             else
 675             {
 676                 if (parent->color == ColorFlag::RED)
 677                 {
 678                     p = parent->right;
 679                     if (p->right != nullptr && p->right->color == ColorFlag::RED)
 680                     {
 681                         q = parent;
 682                         parent->color = ColorFlag::BLACK;
 683                         p->color = ColorFlag::RED;
 684                         p->right->color = ColorFlag::BLACK;
 685                         RotateL(parent);
 686 
 687                         if (stackforflashback.empty() == false)
 688                         {
 689                             if (stackforflashback.top()->left == q)
 690                                 stackforflashback.top()->left = parent;
 691                             else
 692                                 stackforflashback.top()->right = parent;
 693                             return root;
 694                         }
 695                         else
 696                         {
 697                             parent->color = ColorFlag::BLACK;
 698                             return parent;
 699                         }
 700                     }
 701                     else
 702                     {
 703                         if (p->left != nullptr && p->left->color == ColorFlag::RED)
 704                         {
 705                             q = parent;
 706                             parent->color = ColorFlag::BLACK;
 707                             RotateRL(parent);
 708 
 709                             if (stackforflashback.empty() == false)
 710                             {
 711                                 if (stackforflashback.top()->left == q)
 712                                     stackforflashback.top()->left = parent;
 713                                 else
 714                                     stackforflashback.top()->right = parent;
 715                                 return root;
 716                             }
 717                             else
 718                             {
 719                                 parent->color = ColorFlag::BLACK;
 720                                 return parent;
 721                             }
 722                         }
 723                         else
 724                         {
 725                             parent->color = ColorFlag::BLACK;
 726                             p->color = ColorFlag::RED;
 727                             return root;
 728                         }
 729                     }
 730                 }
 731                 else
 732                 {
 733                     p = parent->right;
 734                     if (p->color == ColorFlag::BLACK)
 735                     {
 736                         if (p->right != nullptr && p->right->color == ColorFlag::RED)
 737                         {
 738                             q = parent;
 739                             p->right->color = ColorFlag::BLACK;
 740                             RotateL(parent);
 741 
 742                             if (stackforflashback.empty() == false)
 743                             {
 744                                 if (stackforflashback.top()->left == q)
 745                                     stackforflashback.top()->left = parent;
 746                                 else
 747                                     stackforflashback.top()->right = parent;
 748                                 return root;
 749                             }
 750                             else
 751                             {
 752                                 return parent;
 753                             }
 754                         }
 755                         else
 756                         {
 757                             if (p->left != nullptr && p->left->color == ColorFlag::RED)
 758                             {
 759                                 q = parent;
 760                                 p->left->color = ColorFlag::BLACK;
 761                                 RotateRL(parent);
 762 
 763                                 if (stackforflashback.empty() == false)
 764                                 {
 765                                     if (stackforflashback.top()->left == q)
 766                                         stackforflashback.top()->left = parent;
 767                                     else
 768                                         stackforflashback.top()->right = parent;
 769                                     return root;
 770                                 }
 771                                 else
 772                                 {
 773                                     return parent;
 774                                 }
 775                             }
 776                             else
 777                             {
 778                                 q = parent;
 779                                 parent->color = ColorFlag::RED;
 780                                 RotateL(parent);
 781                                 if (stackforflashback.empty() == false)
 782                                 {
 783                                     if (stackforflashback.top()->left == q)
 784                                         stackforflashback.top()->left = parent;
 785                                     else
 786                                         stackforflashback.top()->right = parent;
 787                                     q = parent;
 788                                     parent = stackforflashback.top();
 789                                 }
 790                             }
 791                         }
 792                     }
 793                     else
 794                     {
 795                         q = p->left;
 796                         if (q->right != nullptr && q->right->color == ColorFlag::RED)
 797                         {
 798                             q->right->color = ColorFlag::BLACK;
 799                             q = parent;
 800                             RotateRL(parent);
 801                         }
 802                         else
 803                         {
 804                             if (q->left != nullptr && q->left->color == ColorFlag::RED)
 805                             {
 806                                 q->left->color = ColorFlag::BLACK;
 807                                 q = parent;
 808                                 RotateR(p->left);
 809                                 RotateRL(parent);
 810                             }
 811                             else
 812                             {
 813                                 p->color = ColorFlag::BLACK;
 814                                 q->color = ColorFlag::RED;
 815                                 q = parent;
 816                                 RotateL(parent);
 817                             }
 818                         }
 819 
 820                         if (stackforflashback.empty() == false)
 821                         {
 822                             if (stackforflashback.top()->left == q)
 823                                 stackforflashback.top()->left = parent;
 824                             else
 825                                 stackforflashback.top()->right = parent;
 826                             return root;
 827                         }
 828                         else
 829                         {
 830                             return parent;
 831                         }
 832                     }
 833                 }
 834             }
 835         }
 836         while (stackforflashback.empty() == false);
 837 
 838         return parent;
 839     }
 840     else
 841     {
 842         cout << "红黑树中不存在要删除的数据元素,删除失败" << endl;
 843         return nullptr;
 844     }
 845 }
 846 
 847 template <typename T>
 848 RBTreeNode<T> *InsertRB(RBTreeNode<T> *root, T key)
 849 {
 850     //红黑树插入
 851     if (root == nullptr)
 852         return new RBTreeNode<T>(key, ColorFlag::BLACK);
 853     else
 854     {
 855         stack<RBTreeNode<T> *> stackforflashback;
 856         RBTreeNode<T> *p = root;
 857         while (p != nullptr)   //搜索插入位置
 858         {
 859             stackforflashback.push(p);
 860             if (key < p->data)
 861                 p = p->left;
 862             else if (key > p->data)
 863                 p = p->right;
 864             else
 865             {
 866                 cout << "要插入的关键字在AVL树中已存在,插入失败" << endl;
 867                 return nullptr;
 868             }
 869         }
 870 
 871         if (key < stackforflashback.top()->data)
 872         {
 873             p = stackforflashback.top()->left = new RBTreeNode<T>(key, ColorFlag::RED);
 874         }
 875         else
 876         {
 877             p = stackforflashback.top()->right = new RBTreeNode<T>(key, ColorFlag::RED);
 878         }
 879 
 880         RBTreeNode<T> *q = nullptr;
 881         RBTreeNode<T> *g = nullptr;
 882         while (stackforflashback.empty() == false)  //从第一棵满足循环不变条件的子树(就是新插入的节点)开始逐步向上调整颜色或进行平衡化旋转,直到原红黑树重新恢复平衡为止
 883         {
 884             q = stackforflashback.top();   //进入新一轮循环后p为满足循环不变条件的子树的根节点,stackforflashback栈顶指针为其父节点指针
 885             stackforflashback.pop();
 886 
 887             if (q->color == ColorFlag::BLACK)
 888                 return root;
 889             else
 890             {
 891                 if (q->left == p)
 892                 {
 893                     g = stackforflashback.top();
 894                     stackforflashback.pop();
 895                     if (g->left == q)
 896                     {
 897                         if (g->right != nullptr && g->right->color == ColorFlag::RED)
 898                         {
 899                             p = g;
 900                             g->color = ColorFlag::RED;
 901                             g->right->color = ColorFlag::BLACK;
 902                             q->color = ColorFlag::BLACK;
 903                             if (stackforflashback.empty() == false)
 904                             {
 905                                 if (stackforflashback.top()->left == p)
 906                                     stackforflashback.top()->left = g;
 907                                 else
 908                                     stackforflashback.top()->right = g;
 909                                 p = g;
 910                             }
 911                             else
 912                             {
 913                                 g->color = ColorFlag::BLACK;
 914                             }
 915                         }
 916                         else
 917                         {
 918                             g->color = ColorFlag::RED;
 919                             q->color = ColorFlag::BLACK;
 920                             p = g;
 921                             RotateR(g);
 922 
 923                             if (stackforflashback.empty() == false)
 924                             {
 925                                 if (stackforflashback.top()->left == p)
 926                                     stackforflashback.top()->left = g;
 927                                 else
 928                                     stackforflashback.top()->right = g;
 929                                 return root;
 930                             }
 931                             else
 932                             {
 933                                 return g;
 934                             }
 935                         }
 936                     }
 937                     else
 938                     {
 939                         if (g->left != nullptr && g->left->color == ColorFlag::RED)
 940                         {
 941                             p = g;
 942                             q->color = ColorFlag::BLACK;
 943                             RotateRL(g);
 944 
 945                             if (stackforflashback.empty() == false)
 946                             {
 947                                 if (stackforflashback.top()->left == p)
 948                                     stackforflashback.top()->left = g;
 949                                 else
 950                                     stackforflashback.top()->right = g;
 951                                 p = g;
 952                             }
 953                             else
 954                             {
 955                                 g->color = ColorFlag::BLACK;
 956                             }
 957                         }
 958                         else
 959                         {
 960                             g->color = ColorFlag::RED;
 961                             p->color = ColorFlag::BLACK;
 962                             p = g;
 963                             RotateRL(g);
 964 
 965                             if (stackforflashback.empty() == false)
 966                             {
 967                                 if (stackforflashback.top()->left == p)
 968                                     stackforflashback.top()->left = g;
 969                                 else
 970                                     stackforflashback.top()->right = g;
 971                                 return root;
 972                             }
 973                             else
 974                             {
 975                                 return g;
 976                             }
 977                         }
 978                     }
 979                 }
 980                 else
 981                 {
 982                     g = stackforflashback.top();
 983                     stackforflashback.pop();
 984                     if (g->right == q)
 985                     {
 986                         if (g->left != nullptr && g->left->color == ColorFlag::RED)
 987                         {
 988                             p = g;
 989                             g->color = ColorFlag::RED;
 990                             g->left->color = ColorFlag::BLACK;
 991                             q->color = ColorFlag::BLACK;
 992                             if (stackforflashback.empty() == false)
 993                             {
 994                                 if (stackforflashback.top()->left == p)
 995                                     stackforflashback.top()->left = g;
 996                                 else
 997                                     stackforflashback.top()->right = g;
 998                                 p = g;
 999                             }
1000                             else
1001                             {
1002                                 g->color = ColorFlag::BLACK;
1003                             }
1004                         }
1005                         else
1006                         {
1007                             g->color = ColorFlag::RED;
1008                             q->color = ColorFlag::BLACK;
1009                             p = g;
1010                             RotateL(g);
1011 
1012                             if (stackforflashback.empty() == false)
1013                             {
1014                                 if (stackforflashback.top()->left == p)
1015                                     stackforflashback.top()->left = g;
1016                                 else
1017                                     stackforflashback.top()->right = g;
1018                                 return root;
1019                             }
1020                             else
1021                             {
1022                                 return g;
1023                             }
1024                         }
1025                     }
1026                     else
1027                     {
1028                         if (g->right != nullptr && g->right->color == ColorFlag::RED)
1029                         {
1030                             p = g;
1031                             q->color = ColorFlag::BLACK;
1032                             RotateLR(g);
1033 
1034                             if (stackforflashback.empty() == false)
1035                             {
1036                                 if (stackforflashback.top()->left == p)
1037                                     stackforflashback.top()->left = g;
1038                                 else
1039                                     stackforflashback.top()->right = g;
1040                                 p = g;
1041                             }
1042                             else
1043                             {
1044                                 g->color = ColorFlag::BLACK;
1045                             }
1046                         }
1047                         else
1048                         {
1049                             g->color = ColorFlag::RED;
1050                             p->color = ColorFlag::BLACK;
1051                             p = g;
1052                             RotateLR(g);
1053 
1054                             if (stackforflashback.empty() == false)
1055                             {
1056                                 if (stackforflashback.top()->left == p)
1057                                     stackforflashback.top()->left = g;
1058                                 else
1059                                     stackforflashback.top()->right = g;
1060                                 return root;
1061                             }
1062                             else
1063                             {
1064                                 return g;
1065                             }
1066                         }
1067                     }
1068                 }
1069             }
1070         }
1071         return g;
1072     }
1073 }
1074 
1075 template <typename T>
1076 int Searchd(RBTreeNode<T> *ptr, int d)
1077 {
1078     if (d == 2)
1079         return 0;
1080     else
1081     {
1082         if (d == 1)
1083         {
1084             if (ptr->right == nullptr)
1085                 return 0;
1086             else
1087                 return 2;
1088         }
1089         else
1090         {
1091             if (ptr->left != nullptr)
1092                 return 1;
1093             else
1094             {
1095                 if (ptr->right != nullptr)
1096                     return 2;
1097                 else
1098                     return 0;
1099             }
1100         }
1101     }
1102 }
1103 
1104 template <typename T>
1105 void output(RBTreeNode<T> *ptr)  //输出以ptr为根的红黑树对应的广义表形式
1106 {
1107     struct memory
1108     {
1109         RBTreeNode<T> *p;
1110         int direction;
1111         int last;
1112         memory(RBTreeNode<T> *p, int d, int l) :p(p), direction(d), last(l) {}
1113     };
1114     int d = 0;
1115     RBTreeNode<T> *const dest = ptr;
1116     stack<memory> arrange;
1117     while (true)
1118     {
1119         if (Searchd(ptr, d) == 0)
1120         {
1121             if (ptr == dest)
1122             {
1123                 if (d == 0)
1124                     cout << ptr->data << "(";
1125                 else
1126                 {
1127                     if (arrange.top().last == 1)
1128                         cout << ", ";
1129                 }
1130                 cout << ")";
1131                 break;
1132             }
1133             else
1134             {
1135                 if (d == 0)
1136                 {
1137                     if (arrange.top().last == 0)
1138                     {
1139                         if (arrange.top().direction == 1)
1140                         {
1141                             cout << ptr->data;
1142                             arrange.top().last = 1;
1143                         }
1144                         else
1145                         {
1146                             cout << " ," << ptr->data;
1147                             arrange.top().last = 2;
1148                         }
1149                     }
1150                     else
1151                     {
1152                         cout << ",";
1153                         cout << ptr->data;
1154                         arrange.top().last = 2;
1155                     }
1156                 }
1157                 else
1158                 {
1159                     if (arrange.top().last == 2)
1160                         cout << ")";
1161                     else
1162                     {
1163                         cout << ", )";
1164                     }
1165                     arrange.pop();
1166                 }
1167                 ptr = arrange.top().p;
1168                 d = arrange.top().direction;
1169             }
1170         }
1171         else
1172         {
1173             RBTreeNode<T> *interval = nullptr;
1174             if (d == 0)
1175             {
1176                 if (arrange.empty() == false)
1177                 {
1178                     if (arrange.top().last == 0)
1179                     {
1180                         if (arrange.top().direction == 1)
1181                         {
1182                             cout << ptr->data << "(";
1183                             arrange.top().last = 1;
1184                         }
1185                         else
1186                         {
1187                             cout << " ," << ptr->data << "(";
1188                             arrange.top().last = 2;
1189                         }
1190                     }
1191                     else
1192                     {
1193                         cout << ",";
1194                         cout << ptr->data << "(";
1195                         arrange.top().last = 2;
1196                     }
1197                 }
1198                 else
1199                 {
1200                     cout << ptr->data << "(";
1201                 }
1202                 arrange.push(memory(ptr, Searchd(ptr, d), 0));
1203                 if (arrange.top().direction == 1)
1204                     interval = ptr->left;
1205                 else
1206                     interval = ptr->right;
1207             }
1208             else
1209             {
1210                 arrange.top().direction = 2;
1211                 interval = ptr->right;
1212             }
1213             d = 0;
1214             ptr = interval;
1215         }
1216     }
1217 }
1218 
1219 int main()
1220 {
1221     vector<TYPE> insertvalue{ 13, 2, 6, 5, 16, 14, 1, 20, 12, 4, 3, 15, 18, 21, 30, 11, 17, 25, 19, 29 };
1222     RBTreeNode<TYPE> *root = nullptr;
1223     for (vector<TYPE>::const_iterator p = insertvalue.cbegin(); p != insertvalue.cend(); ++p)
1224     {
1225         root = InsertRB(root, *p);
1226         cout << "插入"<< *p <<endl;
1227         output(root);
1228         cout << endl;
1229         if (isRB(root) == true)
1230         {
1231             cout << "当前树是红黑树";
1232             cout << endl;
1233         }
1234         else
1235         {
1236             cerr << "错误当前树不是红黑树!" << endl;
1237             exit(0);
1238         }
1239     }
1240     cout << endl;
1241     cout << "插入完成后删除前红黑树对应的广义表形式为:" << endl;
1242     output(root);
1243     cout << endl;
1244     cout << endl;
1245     for (vector<TYPE>::const_iterator p = insertvalue.cbegin(); p != insertvalue.cend(); ++p)
1246     {
1247         cout << "删除节点" << *p << endl;
1248         root = DelRB(root, *p);
1249         if (root != nullptr)
1250         {
1251             output(root);
1252             cout << endl;
1253             if (isRB(root) == true)
1254             {
1255                 cout << "当前树是红黑树";
1256                 cout << endl;
1257             }
1258             else
1259             {
1260                 cerr << "错误当前树不是红黑树!" << endl;
1261                 exit(0);
1262             }
1263         }
1264         else
1265             cout << "NULL";
1266         cout << endl;
1267     }
1268     return 0;
1269 }

运行结果:

 技术分享图片


以上是关于数据结构备忘录:红黑树的插入与删除的主要内容,如果未能解决你的问题,请参考以下文章

红黑树的插入与删除

数据结构 - 红黑树(Red Black Tree)删除详解与实现(Java)

红黑树插入与删除

红黑树插入删除详细步骤动画演示与AVL树的区别

红黑树的性质与包括旋转插入删除等操作(下)

红黑树详解——数据删除操作