ToB企服应用市场:ToB评测及商务社交产业平台

标题: 【C++】红黑树 [打印本页]

作者: 怀念夏天    时间: 2024-9-6 10:55
标题: 【C++】红黑树
前言:

   AVL树是二叉平衡搜索树,红黑树是基于AVL树的改造,是基于旋转的次数的减少。
  红黑树简介

红黑树的性质

红黑树操作

红黑树是一种自平衡的二叉搜索树,它通过在每个节点上添加颜色属性(红色或黑色)并遵循特定的规则来保持树的平衡,从而包管了插入、删除和查找操作的对数时间复杂度。
在C++中实现红黑树通常涉及以下步调:
红黑树的实现

存储结构


  1. enum Colour
  2. {
  3.     RED,
  4.     BLACK
  5. };
  6. template<class K, class V>
  7.     class RBTreeNode
  8.     {
  9.         public:
  10.         RBTreeNode<K, V>* _left;
  11.         RBTreeNode<K, V>* _right;
  12.         RBTreeNode<K, V>* _parent;
  13.         pair<K, V> _kv;
  14.         Colour _col;
  15.         RBTreeNode(const pair<K, V>& kv)
  16.             :_left(nullptr), _right(nullptr), _parent(nullptr), _col(RED), _kv(kv)
  17.             {}
  18.     };
复制代码
红黑树的插入、


  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 (kv.first > cur->_kv.first)
  14.         {
  15.             parent = cur;
  16.             cur = cur->_right;
  17.         }
  18.         else if (kv.first < cur->_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.     cur->_col = RED;
  30.     if (kv.first < parent->_kv.first)
  31.     {
  32.         parent->_left = cur;
  33.     }
  34.     else
  35.     {
  36.         parent->_right = cur;
  37.     }
  38.     cur->_parent = parent;、
  39.     //调账
  40.   ...
  41. }
复制代码
调解(旋转)


左旋

  1. void RotateL(Node* parent)
  2. {
  3.         Node* cur = parent->_right;
  4.         Node* curleft = cur->_left;
  5.         parent->_right = curleft;
  6.         if (curleft)
  7.         {
  8.                 curleft->_parent = parent;
  9.         }
  10.         cur->_left = parent;
  11.         Node* ppnode = parent->_parent;
  12.         parent->_parent = cur;
  13.         if (parent == _root)
  14.         {
  15.                 _root = cur;
  16.                 cur->_parent = nullptr;
  17.         }
  18.         else
  19.         {
  20.                 if (ppnode->_left == parent)
  21.                 {
  22.                         ppnode->_left = cur;
  23.                 }
  24.                 else
  25.                 {
  26.                         ppnode->_right = cur;
  27.                 }
  28.                 cur->_parent = ppnode;
  29.         }
  30. }
复制代码
右旋

  1. void RotateR(Node* parent)
  2. {
  3.         Node* cur = parent->_left;
  4.         Node* curright = cur->_right;
  5.         parent->_left = curright;
  6.         if (curright)
  7.         {
  8.                 curright->_parent = parent;
  9.         }
  10.         cur->_right = parent;
  11.         Node* ppnode = parent->_parent;
  12.         parent->_parent = cur;
  13.         if (ppnode == nullptr)
  14.         {
  15.                 _root = cur;
  16.                 cur->_parent = nullptr;
  17.         }
  18.         else
  19.         {
  20.                 if (ppnode->_left == parent)
  21.                 {
  22.                         ppnode->_left = cur;
  23.                 }
  24.                 else
  25.                 {
  26.                         ppnode->_right = cur;
  27.                 }
  28.                 cur->_parent = ppnode;
  29.         }
  30. }
复制代码
导致红黑树的不平衡缘故原由


环境一



环境二



如何包管红黑树平衡


  1. while (parent && parent->_col == RED)
  2. {
  3.     Node* grandparent = parent->_parent;
  4.     if (parent == grandparent->_left)
  5.     {
  6.         Node* uncle = grandparent->_right;
  7.         if (uncle && uncle->_col == RED)
  8.         {
  9.             parent->_col = uncle->_col = BLACK;
  10.             grandparent->_col = RED;
  11.             cur = grandparent;
  12.             parent = cur->_parent;
  13.         }
  14.         else//uncle is not or black
  15.         {
  16.             if (cur == parent->_left)
  17.             {
  18.                 RotateR(grandparent);
  19.                 grandparent->_col = RED;
  20.                 parent->_col = BLACK;
  21.             }
  22.             else
  23.             {
  24.                 RotateL(parent);
  25.                 RotateR(grandparent);
  26.                 grandparent->_col = RED;
  27.                 cur->_col = BLACK;
  28.             }
  29.             break;
  30.         }
  31.     }
  32.     else//parent == grandparent->_right
  33.     {
  34.         Node* uncle = grandparent->_left;
  35.         if (uncle && uncle->_col == RED)
  36.         {
  37.             grandparent->_col = RED;
  38.             parent->_col = uncle->_col= BLACK;
  39.             cur = grandparent;
  40.             parent = cur->_parent;
  41.         }
  42.         else
  43.         {
  44.             if (cur == parent->_right)
  45.             {
  46.                 RotateL(grandparent);
  47.                 parent->_col = BLACK;
  48.                 grandparent->_col = RED;
  49.             }
  50.             else
  51.             {
  52.                 RotateR(parent);
  53.                 RotateL(grandparent);
  54.                 cur->_col = BLACK;
  55.                 grandparent->_col = RED;
  56.             }
  57.         }
  58.         break;
  59.     }
  60. }
复制代码
红黑树平衡的验证


  1. bool is_balance(Node* root)
  2. {
  3.     if (root == nullptr)
  4.     {
  5.         return true;
  6.     }
  7.     if (root->_col == RED)
  8.     {
  9.         return false;
  10.     }
  11.     int stdnum = 0;
  12.     Node* cur = root;
  13.     while (cur)
  14.     {
  15.         if (cur->_col == BLACK)
  16.         {
  17.             ++stdnum;
  18.         }
  19.         cur = cur->_left;
  20.     }
  21.     return Checknum(root, 0, stdnum);
  22. }
复制代码
查抄黑色节点


  1. bool Checknum(Node* root, int blacknum, int stdnum)
  2. {
  3.     if (root == nullptr)
  4.     {
  5.         if (blacknum != stdnum)
  6.         {
  7.             return false;
  8.         }
  9.         return true;
  10.     }
  11.     if (root->_col == BLACK)
  12.     {
  13.         ++blacknum;
  14.     }
  15.     return Checknum(root->_left, blacknum, stdnum)
  16.         && Checknum(root->_right, blacknum, stdnum);
  17. }
复制代码
源码

  1. #pragma once
  2. #include<iostream>
  3. #include<assert.h>
  4. #include<utility>
  5. using namespace std;
  6. namespace RBTree
  7. {
  8.         enum Colour
  9.         {
  10.                 RED,
  11.                 BLACK
  12.         };
  13.         template<class K, class V>
  14.         class RBTreeNode
  15.         {
  16.         public:
  17.                 RBTreeNode<K, V>* _left;
  18.                 RBTreeNode<K, V>* _right;
  19.                 RBTreeNode<K, V>* _parent;
  20.                 pair<K, V> _kv;
  21.                 Colour _col;
  22.                 RBTreeNode(const pair<K, V>& kv)
  23.                         :_left(nullptr), _right(nullptr), _parent(nullptr), _col(RED), _kv(kv)
  24.                 {}
  25.         };
  26.         template<class K, class V>
  27.         class RBTree
  28.         {
  29.                 typedef RBTreeNode<K, V> Node;
  30.         public:
  31.                 bool is_balance()
  32.                 {
  33.                         return is_balance(_root);
  34.                 }
  35.                 bool Checknum(Node* root, int blacknum, int stdnum)
  36.                 {
  37.                         if (root == nullptr)
  38.                         {
  39.                                 if (blacknum != stdnum)
  40.                                 {
  41.                                         return false;
  42.                                 }
  43.                                 return true;
  44.                         }
  45.                         if (root->_col == BLACK)
  46.                         {
  47.                                 ++blacknum;
  48.                         }
  49.                         return Checknum(root->_left, blacknum, stdnum)
  50.                                 && Checknum(root->_right, blacknum, stdnum);
  51.                 }
  52.                 bool is_balance(Node* root)
  53.                 {
  54.                         if (root == nullptr)
  55.                         {
  56.                                 return true;
  57.                         }
  58.                         if (root->_col == RED)
  59.                         {
  60.                                 return false;
  61.                         }
  62.                         int stdnum = 0;
  63.                         Node* cur = root;
  64.                         while (cur)
  65.                         {
  66.                                 if (cur->_col == BLACK)
  67.                                 {
  68.                                         ++stdnum;
  69.                                 }
  70.                                 cur = cur->_left;
  71.                         }
  72.                         return Checknum(root, 0, stdnum);
  73.                 }
  74.                 bool insert(const pair<K, V>& kv)
  75.                 {
  76.                         if (_root == nullptr)
  77.                         {
  78.                                 _root = new Node(kv);
  79.                                 _root->_col = BLACK;
  80.                                 return true;
  81.                         }
  82.                         Node* parent = nullptr;
  83.                         Node* cur = _root;
  84.                         while (cur)
  85.                         {
  86.                                 if (kv.first > cur->_kv.first)
  87.                                 {
  88.                                         parent = cur;
  89.                                         cur = cur->_right;
  90.                                 }
  91.                                 else if (kv.first < cur->_kv.first)
  92.                                 {
  93.                                         parent = cur;
  94.                                         cur = cur->_left;
  95.                                 }
  96.                                 else
  97.                                 {
  98.                                         return false;
  99.                                 }
  100.                         }
  101.                         cur = new Node(kv);
  102.                         cur->_col = RED;
  103.                         if (kv.first < parent->_kv.first)
  104.                         {
  105.                                 parent->_left = cur;
  106.                         }
  107.                         else
  108.                         {
  109.                                 parent->_right = cur;
  110.                         }
  111.                         cur->_parent = parent;
  112.                         while (parent && parent->_col == RED)
  113.                         {
  114.                                 Node* grandparent = parent->_parent;
  115.                                 if (parent == grandparent->_left)
  116.                                 {
  117.                                         Node* uncle = grandparent->_right;
  118.                                         if (uncle && uncle->_col == RED)
  119.                                         {
  120.                                                 parent->_col = uncle->_col = BLACK;
  121.                                                 grandparent->_col = RED;
  122.                                                 cur = grandparent;
  123.                                                 parent = cur->_parent;
  124.                                         }
  125.                                         else//uncle is not or black
  126.                                         {
  127.                                                 if (cur == parent->_left)
  128.                                                 {
  129.                                                         RotateR(grandparent);
  130.                                                         grandparent->_col = RED;
  131.                                                         parent->_col = BLACK;
  132.                                                 }
  133.                                                 else
  134.                                                 {
  135.                                                         RotateL(parent);
  136.                                                         RotateR(grandparent);
  137.                                                         grandparent->_col = RED;
  138.                                                         cur->_col = BLACK;
  139.                                                 }
  140.                                                 break;
  141.                                         }
  142.                                 }
  143.                                 else//parent == grandparent->_right
  144.                                 {
  145.                                         Node* uncle = grandparent->_left;
  146.                                         if (uncle && uncle->_col == RED)
  147.                                         {
  148.                                                 grandparent->_col = RED;
  149.                                                 parent->_col = uncle->_col= BLACK;
  150.                                                 cur = grandparent;
  151.                                                 parent = cur->_parent;
  152.                                         }
  153.                                         else
  154.                                         {
  155.                                                 if (cur == parent->_right)
  156.                                                 {
  157.                                                         RotateL(grandparent);
  158.                                                         parent->_col = BLACK;
  159.                                                         grandparent->_col = RED;
  160.                                                 }
  161.                                                 else
  162.                                                 {
  163.                                                         RotateR(parent);
  164.                                                         RotateL(grandparent);
  165.                                                         cur->_col = BLACK;
  166.                                                         grandparent->_col = RED;
  167.                                                 }
  168.                                         }
  169.                                         break;
  170.                                 }
  171.                         }
  172.                         _root->_col = BLACK;
  173.                         return true;
  174.                 }
  175.                 void RotateR(Node* parent)
  176.                 {
  177.                         Node* cur = parent->_left;
  178.                         Node* curright = cur->_right;
  179.                         parent->_left = curright;
  180.                         if (curright)
  181.                         {
  182.                                 curright->_parent = parent;
  183.                         }
  184.                         cur->_right = parent;
  185.                         Node* ppnode = parent->_parent;
  186.                         parent->_parent = cur;
  187.                         if (ppnode == nullptr)
  188.                         {
  189.                                 _root = cur;
  190.                                 cur->_parent = nullptr;
  191.                         }
  192.                         else
  193.                         {
  194.                                 if (ppnode->_left == parent)
  195.                                 {
  196.                                         ppnode->_left = cur;
  197.                                 }
  198.                                 else
  199.                                 {
  200.                                         ppnode->_right = cur;
  201.                                 }
  202.                                 cur->_parent = ppnode;
  203.                         }
  204.                 }
  205.                 void RotateL(Node* parent)
  206.                 {
  207.                         Node* cur = parent->_right;
  208.                         Node* curleft = cur->_left;
  209.                         parent->_right = curleft;
  210.                         if (curleft)
  211.                         {
  212.                                 curleft->_parent = parent;
  213.                         }
  214.                         cur->_left = parent;
  215.                         Node* ppnode = parent->_parent;
  216.                         parent->_parent = cur;
  217.                         if (parent == _root)
  218.                         {
  219.                                 _root = cur;
  220.                                 cur->_parent = nullptr;
  221.                         }
  222.                         else
  223.                         {
  224.                                 if (ppnode->_left == parent)
  225.                                 {
  226.                                         ppnode->_left = cur;
  227.                                 }
  228.                                 else
  229.                                 {
  230.                                         ppnode->_right = cur;
  231.                                 }
  232.                                 cur->_parent = ppnode;
  233.                         }
  234.                 }
  235.         private:
  236.                 Node* _root = nullptr;
  237.         };
  238. }
  239.         }
  240.                 void RotateL(Node* parent)
  241.                 {
  242.                         Node* cur = parent->_right;
  243.                         Node* curleft = cur->_left;
  244.                         parent->_right = curleft;
  245.                         if (curleft)
  246.                         {
  247.                                 curleft->_parent = parent;
  248.                         }
  249.                         cur->_left = parent;
  250.                         Node* ppnode = parent->_parent;
  251.                         parent->_parent = cur;
  252.                         if (parent == _root)
  253.                         {
  254.                                 _root = cur;
  255.                                 cur->_parent = nullptr;
  256.                         }
  257.                         else
  258.                         {
  259.                                 if (ppnode->_left == parent)
  260.                                 {
  261.                                         ppnode->_left = cur;
  262.                                 }
  263.                                 else
  264.                                 {
  265.                                         ppnode->_right = cur;
  266.                                 }
  267.                                 cur->_parent = ppnode;
  268.                         }
  269.                 }
  270.         private:
  271.                 Node* _root = nullptr;
  272.         };
  273. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4