【红黑树变色+旋转】

曂沅仴駦  金牌会员 | 2024-6-23 12:47:57 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 968|帖子 968|积分 2904

一. 红黑树规则

对于红黑树,举行变色+旋转处置惩罚,终究都是为了维持颜色+以下几条规则,只有颜色和规则维持住了,红黑树就维持住了最长路径的长度不高出最短路径的两倍。
规则:

  • 根是黑的。
  • 没有一连的红节点。
  • 每条路径的黑色数量相称。
二. 环境一叔叔存在且为红

留意点:红黑树插入的节点都是红色的,因为在红黑树中动黑色节点是非常忌讳的,因为要维持每条路径黑色数量相称非常困难,所以插入的节点默认都是红色的。
当插入红色节点后:1.如果父亲为黑或者父亲不存在,结束,不须要任何处置惩罚。
2. 如果父亲存在且为红,由于插入节点为红,存在一连红节点,须要处置惩罚,可以肯定的是爷爷肯定是黑,因为插入节点前就是一棵红黑树了,既然父亲和爷爷颜色确定,重要看叔叔。
1.叔叔存在且为红


环境二.变色+旋旋

叔叔存在且为黑或者叔叔不存在都需变色+旋转,关键分析是左单旋,右单旋,照旧左右双旋,照旧右左双旋只要旋转后,就均衡了,直接结束,不须要向上更新
1. 变色+单旋

对于叔叔存在且为黑或不存在这种环境,不大概是因为直接插入红色节点导致一连红这种环境直接发生的,因为这发生了,原本就不是红黑树,肯定是由上述图一第一种环境处置惩罚更新上来导致的。
办理办法:curp->left, pg->left 左左右单旋g点+
p变黑,g变红。
同理:如果上述环境curp->right, pg->right,右右左单旋g点+p变黑,g变红
2.变色+双旋

对于这种环境:curp->right, pg->left,左右双旋,
将p左旋,g右旋,+ cur变黑+g变红。
同理:curp->left, pg->right, 右左双旋,将p右旋,g左旋,+cur变黑+g变红
总结单纯变色处置惩罚,须要不停向上更新至父亲不存在或者父亲为黑结束,旋转+变色处置惩罚完就均衡了直接结束。
一下是代码实现
  1. bool Insert(const pair<K, V>& kv)
  2.                 {
  3.                         if (_root == nullptr)
  4.                         {
  5.                                 _root = new Node(kv);
  6.                                 _root->_col = BLACK;        //根为黑色
  7.                                 return true;
  8.                         }
  9.                         Node* parent = nullptr;
  10.                         Node* cur = _root;
  11.                         while (cur)
  12.                         {
  13.                                 if (cur->_kv.first < kv.first)
  14.                                 {
  15.                                         parent = cur;
  16.                                         cur = cur->_right;
  17.                                 }
  18.                                 else if (cur->_kv.first > kv.first)
  19.                                 {
  20.                                         parent = cur;
  21.                                         cur = cur->_left;
  22.                                 }
  23.                                 else
  24.                                 {
  25.                                         return false;
  26.                                 }
  27.                         }
  28.                         cur = new Node(kv);
  29.                         if (parent->_kv.first < kv.first)
  30.                         {
  31.                                 parent->_right = cur;
  32.                         }
  33.                         else
  34.                         {
  35.                                 parent->_left = cur;
  36.                         }
  37.                         cur->_parent = parent;
  38.                         //父亲存在且为红,连续红节点,处理(如果父亲不存在管你红黑就结束了,如果为黑也结束了)
  39.                         while (parent && parent->_col == RED)
  40.                         {
  41.                                 Node* grandfather = parent->_parent;  //算出爷爷,根据父亲为爷爷的左右,确定叔叔
  42.                                 if (parent == grandfather->_left)
  43.                                 {
  44.                                         Node* uncle = grandfather->_right;
  45.                                         //情况一:叔叔存在且为红 变色处理
  46.                                         if (uncle && uncle->_col == RED)
  47.                                         {
  48.                                                 parent->_col = uncle->_col = BLACK;
  49.                                                 grandfather->_col = RED;
  50.                                                 //根节点保证为黑下面处理
  51.                                                 //继续往上处理
  52.                                                 cur = grandfather;
  53.                                                 parent = cur->_parent;
  54.                                         }
  55.                                         //情况二:叔叔不存在/叔叔存在且为黑
  56.                                         else
  57.                                         {
  58.                                                 //需要判别单旋还是左旋,确定cur的位置
  59.                                                 //旋转+变色
  60.                                                 if (cur == parent->_left)
  61.                                                 {
  62.                                                         //                g
  63.                                                         //         p                u
  64.                                                         //c
  65.                                                         //左左右单旋
  66.                                                         RotateR(grandfather);
  67.                                                         parent->_col = BLACK;
  68.                                                         grandfather->_col = RED;
  69.                                                 }
  70.                                                 else
  71.                                                 {
  72.                                                         //                g
  73.                                                         //        p                u
  74.                                                         //           c
  75.                                                         //左右双旋+变色
  76.                                                         RotateL(parent);
  77.                                                         RotateR(grandfather);
  78.                                                         cur->_col = BLACK;
  79.                                                         grandfather->_col = RED;
  80.                                                 }
  81.                                                 break;        //只要旋转结束就平衡了结束
  82.                                         }
  83.                                 }
  84.                                 else
  85.                                 {
  86.                                         Node* uncle = grandfather->_left;
  87.                                         //情况一:叔叔存在且为红 变色处理
  88.                                         if (uncle && uncle->_col == RED)
  89.                                         {
  90.                                                 parent->_col = uncle->_col = BLACK;
  91.                                                 grandfather->_col = RED;
  92.                                                 //根节点保证为黑下面处理
  93.                                                 //继续往上处理
  94.                                                 cur = grandfather;
  95.                                                 parent = cur->_parent;
  96.                                         }
  97.                                         //情况二:叔叔不存在/叔叔存在且为黑
  98.                                         else
  99.                                         {
  100.                                                 if (cur == parent->_right)
  101.                                                 {
  102.                                                         //                g
  103.                                                         //        u                p
  104.                                                         //                                c
  105.                                                         RotateL(grandfather);
  106.                                                         parent->_col = BLACK;
  107.                                                         grandfather->_col = RED;
  108.                                                 }
  109.                                                 else
  110.                                                 {
  111.                                                         //                g
  112.                                                         //        u                p
  113.                                                         //                 c
  114.                                                         //右左双旋
  115.                                                         RotateR(parent);
  116.                                                         RotateL(grandfather);
  117.                                                         cur->_col = BLACK;
  118.                                                         grandfather->_col = RED;
  119.                                                 }
  120.                                                 //只要旋转完了,就平衡结束了
  121.                                                 break;
  122.                                         }
  123.                                 }
  124.                         }
  125.                         _root->_col = BLACK;        //变色没有处理根,无论怎么处理都保证根是黑的
  126.                         return true;
  127.                 }
  128.                 void RotateL(Node* parent)
  129.                 {
  130.                         ++rotateSize;
  131.                         Node* subR = parent->_right;
  132.                         Node* subRL = subR->_left;
  133.                         parent->_right = subRL;
  134.                         if (subRL)
  135.                                 subRL->_parent = parent;
  136.                         subR->_left = parent;
  137.                         Node* ppnode = parent->_parent;
  138.                         parent->_parent = subR;
  139.                         if (_root == parent)
  140.                         {
  141.                                 _root = subR;
  142.                                 subR->_parent = nullptr;
  143.                         }
  144.                         else
  145.                         {
  146.                                 if (parent == ppnode->_left)
  147.                                 {
  148.                                         ppnode->_left = subR;
  149.                                 }
  150.                                 else
  151.                                 {
  152.                                         ppnode->_right = subR;
  153.                                 }
  154.                                 subR->_parent = ppnode;
  155.                         }
  156.                 }
  157.                 void RotateR(Node* parent)
  158.                 {
  159.                         ++rotateSize;
  160.                         Node* subL = parent->_left;
  161.                         Node* subLR = subL->_right;
  162.                         parent->_left = subLR;
  163.                         if (subLR)
  164.                                 subLR->_parent = parent;
  165.                         subL->_right = parent;
  166.                         Node* ppnode = parent->_parent;
  167.                         parent->_parent = subL;
  168.                         if (parent == _root)
  169.                         {
  170.                                 _root = subL;
  171.                                 subL->_parent = nullptr;
  172.                         }
  173.                         else
  174.                         {
  175.                                 if (parent == ppnode->_left)
  176.                                 {
  177.                                         ppnode->_left = subL;
  178.                                 }
  179.                                 else
  180.                                 {
  181.                                         ppnode->_right = subL;
  182.                                 }
  183.                                 subL->_parent = ppnode;
  184.                         }
  185.                 }
  186.                
复制代码
无论怎么方式处置惩罚完都须要包管根是黑的,最后加上

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

曂沅仴駦

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表