【C++】:STL详解 —— 红黑树封装map和set

打印 上一主题 下一主题

主题 1030|帖子 1030|积分 3090

目次

红黑树的源代码
正向迭代器的代码
反向迭代器的代码
set的模拟实现
map的模拟实现


红黑树的源代码

  1. #pragma once
  2. #include <iostream>
  3. using namespace std;
  4. // set ->key
  5. // map ->key/value
  6. // set ->key
  7. // map ->key/value
  8. enum Colour
  9. {
  10.         RED,
  11.         BLACK
  12. };
  13. template<class T>
  14. struct RBTreeNode
  15. {
  16.         RBTreeNode<T>* _left;
  17.         RBTreeNode<T>* _right;
  18.         RBTreeNode<T>* _parent;
  19.         T _data;
  20.         Colour _col;
  21.         RBTreeNode(const T& data)
  22.                 :_left(nullptr)
  23.                 , _right(nullptr)
  24.                 , _parent(nullptr)
  25.                 , _data(data)
  26.                 , _col(RED)
  27.         {}
  28. };
  29. // 红黑树正向迭代器模板
  30. // 模板参数:
  31. //   T    - 结点数据类型
  32. //   Ref  - 数据的引用类型
  33. //   Ptr  - 数据的指针类型
  34. template<class T, class Ref, class Ptr>
  35. struct __TreeIterator
  36. {
  37.         typedef RBTreeNode<T> Node;                                        // 红黑树结点类型
  38.         typedef __TreeIterator<T, Ref, Ptr> Self;        // 迭代器自身类型
  39.         Node* _node;                                                                // 当前迭代器持有的结点指针
  40.         // 构造函数
  41.         // 参数:
  42.         //   node - 需要包装的结点指针
  43.         __TreeIterator(Node* node)
  44.                 : _node(node)  // 初始化持有的结点指针
  45.         {}
  46.         // 解引用操作符(获取数据引用)
  47.         Ref operator*()
  48.         {
  49.                 return _node->_data;  // 返回结点存储数据的引用
  50.         }
  51.         // 箭头操作符(获取数据指针)
  52.         Ptr operator->()
  53.         {
  54.                 return &_node->_data;  // 返回指向结点数据的指针
  55.         }
  56.         // 不等比较操作符
  57.         // 参数:
  58.         //   s - 要比较的迭代器
  59.         // 返回值: 两个迭代器是否指向不同结点
  60.         bool operator!=(const Self& s) const
  61.         {
  62.                 return _node != s._node;  // 直接比较结点指针
  63.         }
  64.         // 相等比较操作符
  65.         // 参数:
  66.         //   s - 要比较的迭代器
  67.         // 返回值: 两个迭代器是否指向相同结点
  68.         bool operator==(const Self& s) const
  69.         {
  70.                 return _node == s._node;  // 直接比较结点指针
  71.         }
  72.         // 前置自增操作符(中序遍历顺序的下一个结点)
  73.         Self operator++()
  74.         {
  75.                 if (_node->_right)  // 当前结点存在右子树
  76.                 {
  77.                         // 寻找右子树的最左结点(右子树中的最小结点)
  78.                         Node* left = _node->_right;
  79.                         while (left->_left)
  80.                         {
  81.                                 left = left->_left;
  82.                         }
  83.                         _node = left;
  84.                 }
  85.                 else  // 当前结点没有右子树
  86.                 {
  87.                         // 向上寻找第一个不是右孩子的祖先结点
  88.                         Node* cur = _node;
  89.                         Node* parent = cur->_parent;
  90.                         // 沿着父指针向上查找,直到当前结点是父结点的左孩子
  91.                         while (parent && cur == parent->_right)
  92.                         {
  93.                                 cur = parent;
  94.                                 parent = parent->_parent;
  95.                         }
  96.                         _node = parent;  // 最终定位到的父结点即为后继
  97.                 }
  98.                 return *this;
  99.         }
  100.         // 前置自减操作符(中序遍历顺序的前一个结点)
  101.         Self operator--()
  102.         {
  103.                 if (_node->_left)  // 当前结点存在左子树
  104.                 {
  105.                         // 寻找左子树的最右结点(左子树中的最大结点)
  106.                         Node* right = _node->_left;
  107.                         while (right->_right)
  108.                         {
  109.                                 right = right->_right;
  110.                         }
  111.                         _node = right;
  112.                 }
  113.                 else  // 当前结点没有左子树
  114.                 {
  115.                         // 向上寻找第一个不是左孩子的祖先结点
  116.                         Node* cur = _node;
  117.                         Node* parent = cur->_parent;
  118.                         // 沿着父指针向上查找,直到当前结点是父结点的右孩子
  119.                         while (parent && cur == parent->_left)
  120.                         {
  121.                                 cur = parent;
  122.                                 parent = parent->_parent;
  123.                         }
  124.                         _node = parent;  // 最终定位到的父结点即为前驱
  125.                 }
  126.                 return *this;
  127.         }
  128. };
  129. //反向迭代器---迭代器适配器
  130. template<class Iterator>
  131. struct ReverseIterator
  132. {
  133.         typedef ReverseIterator<Iterator> Self; //反向迭代器的类型
  134.         typedef typename Iterator::reference Ref; //结点指针的引用
  135.         typedef typename Iterator::pointer Ptr; //结点指针
  136.         Iterator _it; //反向迭代器所封装的正向迭代器
  137.         //构造函数
  138.         ReverseIterator(Iterator it)
  139.                 :_it(it) //根据所给正向迭代器构造一个反向迭代器
  140.         {}
  141.         Ref operator*()
  142.         {
  143.                 return *_it; //通过调用正向迭代器的operator*返回结点数据的引用
  144.         }
  145.         Ptr operator->()
  146.         {
  147.                 return _it.operator->(); //通过调用正向迭代器的operator->返回结点数据的指针
  148.         }
  149.         //前置++
  150.         Self& operator++()
  151.         {
  152.                 --_it; //调用正向迭代器的前置--
  153.                 return *this;
  154.         }
  155.         //前置--
  156.         Self& operator--()
  157.         {
  158.                 ++_it; //调用正向迭代器的前置++
  159.                 return *this;
  160.         }
  161.         bool operator!=(const Self& s) const
  162.         {
  163.                 return _it != s._it; //调用正向迭代器的operator!=
  164.         }
  165.         bool operator==(const Self& s) const
  166.         {
  167.                 return _it == s._it; //调用正向迭代器的operator==
  168.         }
  169. };
  170. // set->RBTree<K, K, SetKeyOfT> _t;
  171. // map->RBTree<K, pair<const K, T>, MapKeyOfT> _t;
  172. template<class K, class T, class KeyOfT>
  173. class RBTree
  174. {
  175.         typedef RBTreeNode<T> Node;
  176. public:
  177.         typedef __TreeIterator<T, T&, T*> iterator;                        //正向迭代器
  178.         typedef __TreeIterator<T, const T&, const T*> const_iterator;
  179.         typedef ReverseIterator<iterator> reverse_iterator; //反向迭代器
  180.         typedef ReverseIterator<const_iterator> const_reverse_iterator;
  181.         iterator begin()
  182.         {
  183.                 Node* cur = _root;
  184.                 while (cur && cur->_left)
  185.                 {
  186.                         cur = cur->_left;
  187.                 }
  188.                 return iterator(cur);
  189.         }
  190.         iterator end()
  191.         {
  192.                 return iterator(nullptr);
  193.         }
  194.         const_iterator begin() const
  195.         {
  196.                 Node* cur = _root;
  197.                 while (cur && cur->_left)
  198.                 {
  199.                         cur = cur->_left;
  200.                 }
  201.                 return const_iterator(cur);
  202.         }
  203.         const_iterator end() const
  204.         {
  205.                 return const_iterator(nullptr);
  206.         }
  207.         reverse_iterator rbegin()
  208.         {
  209.                 //寻找最右结点
  210.                 Node* right = _root;
  211.                 while (right && right->_right)
  212.                 {
  213.                         right = right->_right;
  214.                 }
  215.                 //返回最右结点的反向迭代器
  216.                 return reverse_iterator(iterator(right));
  217.         }
  218.         reverse_iterator rend()
  219.         {
  220.                 //返回由nullptr构造得到的反向迭代器(不严谨)
  221.                 return reverse_iterator(iterator(nullptr));
  222.         }
  223.         const_reverse_iterator rbegin() const
  224.         {
  225.                 //寻找最右结点
  226.                 Node* right = _root;
  227.                 while (right && right->_right)
  228.                 {
  229.                         right = right->_right;
  230.                 }
  231.                 //返回最右结点的反向迭代器
  232.                 return const_reverse_iterator(const_iterator(right));
  233.         }
  234.         const_reverse_iterator rend() const
  235.         {
  236.                 //返回由nullptr构造得到的反向迭代器(不严谨)
  237.                 return const_reverse_iterator(const_iterator(nullptr));
  238.         }
  239.         //构造函数
  240.         RBTree()
  241.                 :_root(nullptr)
  242.         {}
  243.         //拷贝构造
  244.         RBTree(const RBTree<K, T, KeyOfT>& t)
  245.         {
  246.                 _root = _Copy(t._root, nullptr);
  247.         }
  248.         //赋值运算符重载(现代写法)
  249.         RBTree<K, T, KeyOfT>& operator=(RBTree<K, T, KeyOfT> t)
  250.         {
  251.                 swap(_root, t._root);
  252.                 return *this; //支持连续赋值
  253.         }
  254.         //析构函数
  255.         ~RBTree()
  256.         {
  257.                 _Destroy(_root);
  258.                 _root = nullptr;
  259.         }
  260.         size_t Size()
  261.         {
  262.                 return _Size(_root);
  263.         }
  264.         bool Empty() const
  265.         {
  266.                 return _root == nullptr;
  267.         }
  268.         void Clear()
  269.         {
  270.                 _Destroy(_root);
  271.                 _root = nullptr;
  272.         }
  273.         void Swap(Node& other)
  274.         {
  275.                 std::swap(_root, other._root);
  276.         }
  277.         //pair<iterator, bool> Insert(const T& data)
  278.         pair<Node*, bool> Insert(const T& data)
  279.         {
  280.                 if (_root == nullptr)
  281.                 {
  282.                         _root = new Node(data);
  283.                         _root->_col = BLACK;
  284.                         return make_pair(_root, true);
  285.                 }
  286.                 Node* parent = nullptr;
  287.                 Node* cur = _root;
  288.                 KeyOfT kot;
  289.                 while (cur)
  290.                 {
  291.                         if (kot(cur->_data) < kot(data))
  292.                         {
  293.                                 parent = cur;
  294.                                 cur = cur->_right;
  295.                         }
  296.                         else if (kot(cur->_data) > kot(data))
  297.                         {
  298.                                 parent = cur;
  299.                                 cur = cur->_left;
  300.                         }
  301.                         else
  302.                         {
  303.                                 return make_pair(cur, false);
  304.                         }
  305.                 }
  306.                 // 新增节点给红色
  307.                 cur = new Node(data);
  308.                 Node* newnode = cur;
  309.                 cur->_col = RED;
  310.                 if (kot(parent->_data) < kot(data))
  311.                 {
  312.                         parent->_right = cur;
  313.                         cur->_parent = parent;
  314.                 }
  315.                 else
  316.                 {
  317.                         parent->_left = cur;
  318.                         cur->_parent = parent;
  319.                 }
  320.                 while (parent && parent->_col == RED)
  321.                 {
  322.                         Node* grandfather = parent->_parent;
  323.                         if (parent == grandfather->_left)
  324.                         {
  325.                                 //     g
  326.                                 //   p   u
  327.                                 // c
  328.                                 Node* uncle = grandfather->_right;
  329.                                 if (uncle && uncle->_col == RED)
  330.                                 {
  331.                                         // 变色
  332.                                         parent->_col = uncle->_col = BLACK;
  333.                                         grandfather->_col = RED;
  334.                                         // 继续往上更新处理
  335.                                         cur = grandfather;
  336.                                         parent = cur->_parent;
  337.                                 }
  338.                                 else
  339.                                 {
  340.                                         if (cur == parent->_left)
  341.                                         {
  342.                                                 // 单旋
  343.                                                 //     g
  344.                                                 //   p
  345.                                                 // c
  346.                                                 RotateR(grandfather);
  347.                                                 parent->_col = BLACK;
  348.                                                 grandfather->_col = RED;
  349.                                         }
  350.                                         else
  351.                                         {
  352.                                                 // 双旋
  353.                                                 //     g
  354.                                                 //   p
  355.                                                 //     c
  356.                                                 RotateL(parent);
  357.                                                 RotateR(grandfather);
  358.                                                 cur->_col = BLACK;
  359.                                                 grandfather->_col = RED;
  360.                                         }
  361.                                         break;
  362.                                 }
  363.                         }
  364.                         else  // parent == grandfather->_right
  365.                         {
  366.                                 //     g
  367.                                 //   u   p
  368.                                 //          c
  369.                                 //
  370.                                 Node* uncle = grandfather->_left;
  371.                                 if (uncle && uncle->_col == RED)
  372.                                 {
  373.                                         // 变色
  374.                                         parent->_col = uncle->_col = BLACK;
  375.                                         grandfather->_col = RED;
  376.                                         // 继续往上处理
  377.                                         cur = grandfather;
  378.                                         parent = cur->_parent;
  379.                                 }
  380.                                 else
  381.                                 {
  382.                                         if (cur == parent->_right)
  383.                                         {
  384.                                                 RotateL(grandfather);
  385.                                                 parent->_col = BLACK;
  386.                                                 grandfather->_col = RED;
  387.                                         }
  388.                                         else
  389.                                         {
  390.                                                 //     g
  391.                                                 //   u   p
  392.                                                 //     c
  393.                                                 //
  394.                                                 RotateR(parent);
  395.                                                 RotateL(grandfather);
  396.                                                 cur->_col = BLACK;
  397.                                                 grandfather->_col = RED;
  398.                                         }
  399.                                         break;
  400.                                 }
  401.                         }
  402.                 }
  403.                 _root->_col = BLACK;
  404.                 return make_pair(newnode, true);
  405.         }
  406.         //删除函数
  407.         bool Erase(const K& key)
  408.         {
  409.                 KeyOfT kot;
  410.                 //用于遍历二叉树
  411.                 Node* parent = nullptr;
  412.                 Node* cur = _root;
  413.                 //用于标记实际的待删除结点及其父结点
  414.                 Node* delParentPos = nullptr;
  415.                 Node* delPos = nullptr;
  416.                 while (cur)
  417.                 {
  418.                         if (key < kot(cur->_data)) //所给key值小于当前结点的key值
  419.                         {
  420.                                 //往该结点的左子树走
  421.                                 parent = cur;
  422.                                 cur = cur->_left;
  423.                         }
  424.                         else if (key > kot(cur->_data)) //所给key值大于当前结点的key值
  425.                         {
  426.                                 //往该结点的右子树走
  427.                                 parent = cur;
  428.                                 cur = cur->_right;
  429.                         }
  430.                         else //找到了待删除结点
  431.                         {
  432.                                 if (cur->_left == nullptr) //待删除结点的左子树为空
  433.                                 {
  434.                                         if (cur == _root) //待删除结点是根结点
  435.                                         {
  436.                                                 _root = _root->_right; //让根结点的右子树作为新的根结点
  437.                                                 if (_root)
  438.                                                 {
  439.                                                         _root->_parent = nullptr;
  440.                                                         _root->_col = BLACK; //根结点为黑色
  441.                                                 }
  442.                                                 delete cur; //删除原根结点
  443.                                                 return true;
  444.                                         }
  445.                                         else
  446.                                         {
  447.                                                 delParentPos = parent; //标记实际删除结点的父结点
  448.                                                 delPos = cur; //标记实际删除的结点
  449.                                         }
  450.                                         break; //进行红黑树的调整以及结点的实际删除
  451.                                 }
  452.                                 else if (cur->_right == nullptr) //待删除结点的右子树为空
  453.                                 {
  454.                                         if (cur == _root) //待删除结点是根结点
  455.                                         {
  456.                                                 _root = _root->_left; //让根结点的左子树作为新的根结点
  457.                                                 if (_root)
  458.                                                 {
  459.                                                         _root->_parent = nullptr;
  460.                                                         _root->_col = BLACK; //根结点为黑色
  461.                                                 }
  462.                                                 delete cur; //删除原根结点
  463.                                                 return true;
  464.                                         }
  465.                                         else
  466.                                         {
  467.                                                 delParentPos = parent; //标记实际删除结点的父结点
  468.                                                 delPos = cur; //标记实际删除的结点
  469.                                         }
  470.                                         break; //进行红黑树的调整以及结点的实际删除
  471.                                 }
  472.                                 else //待删除结点的左右子树均不为空
  473.                                 {
  474.                                         //替换法删除
  475.                                         //寻找待删除结点右子树当中key值最小的结点作为实际删除结点
  476.                                         Node* minParent = cur;
  477.                                         Node* minRight = cur->_right;
  478.                                         while (minRight->_left)
  479.                                         {
  480.                                                 minParent = minRight;
  481.                                                 minRight = minRight->_left;
  482.                                         }
  483.                                         cur->_data = minRight->_data; //将待删除结点的_data改为minRight的_data
  484.                                         delParentPos = minParent; //标记实际删除结点的父结点
  485.                                         delPos = minRight; //标记实际删除的结点
  486.                                         break; //进行红黑树的调整以及结点的实际删除
  487.                                 }
  488.                         }
  489.                 }
  490.                 if (delPos == nullptr) //delPos没有被修改过,说明没有找到待删除结点
  491.                 {
  492.                         return false;
  493.                 }
  494.                 //记录待删除结点及其父结点(用于后续实际删除)
  495.                 Node* del = delPos;
  496.                 Node* delP = delParentPos;
  497.                 //调整红黑树
  498.                 if (delPos->_col == BLACK) //删除的是黑色结点
  499.                 {
  500.                         if (delPos->_left) //待删除结点有一个红色的左孩子(不可能是黑色)
  501.                         {
  502.                                 delPos->_left->_col = BLACK; //将这个红色的左孩子变黑即可
  503.                         }
  504.                         else if (delPos->_right) //待删除结点有一个红色的右孩子(不可能是黑色)
  505.                         {
  506.                                 delPos->_right->_col = BLACK; //将这个红色的右孩子变黑即可
  507.                         }
  508.                         else //待删除结点的左右均为空
  509.                         {
  510.                                 while (delPos != _root) //可能一直调整到根结点
  511.                                 {
  512.                                         if (delPos == delParentPos->_left) //待删除结点是其父结点的左孩子
  513.                                         {
  514.                                                 Node* brother = delParentPos->_right; //兄弟结点是其父结点的右孩子
  515.                                                 //情况一:brother为红色
  516.                                                 if (brother->_col == RED)
  517.                                                 {
  518.                                                         delParentPos->_col = RED;
  519.                                                         brother->_col = BLACK;
  520.                                                         RotateL(delParentPos);
  521.                                                         //需要继续处理
  522.                                                         brother = delParentPos->_right; //更新brother(否则在本循环中执行其他情况的代码会出错)
  523.                                                 }
  524.                                                 //情况二:brother为黑色,且其左右孩子都是黑色结点或为空
  525.                                                 if (((brother->_left == nullptr) || (brother->_left->_col == BLACK))
  526.                                                         && ((brother->_right == nullptr) || (brother->_right->_col == BLACK)))
  527.                                                 {
  528.                                                         brother->_col = RED;
  529.                                                         if (delParentPos->_col == RED)
  530.                                                         {
  531.                                                                 delParentPos->_col = BLACK;
  532.                                                                 break;
  533.                                                         }
  534.                                                         //需要继续处理
  535.                                                         delPos = delParentPos;
  536.                                                         delParentPos = delPos->_parent;
  537.                                                 }
  538.                                                 else
  539.                                                 {
  540.                                                         //情况三:brother为黑色,且其左孩子是红色结点,右孩子是黑色结点或为空
  541.                                                         if ((brother->_right == nullptr) || (brother->_right->_col == BLACK))
  542.                                                         {
  543.                                                                 brother->_left->_col = BLACK;
  544.                                                                 brother->_col = RED;
  545.                                                                 RotateR(brother);
  546.                                                                 //需要继续处理
  547.                                                                 brother = delParentPos->_right; //更新brother(否则执行下面情况四的代码会出错)
  548.                                                         }
  549.                                                         //情况四:brother为黑色,且其右孩子是红色结点
  550.                                                         brother->_col = delParentPos->_col;
  551.                                                         delParentPos->_col = BLACK;
  552.                                                         brother->_right->_col = BLACK;
  553.                                                         RotateL(delParentPos);
  554.                                                         break; //情况四执行完毕后调整一定结束
  555.                                                 }
  556.                                         }
  557.                                         else //delPos == delParentPos->_right //待删除结点是其父结点的左孩子
  558.                                         {
  559.                                                 Node* brother = delParentPos->_left; //兄弟结点是其父结点的左孩子
  560.                                                 //情况一:brother为红色
  561.                                                 if (brother->_col == RED) //brother为红色
  562.                                                 {
  563.                                                         delParentPos->_col = RED;
  564.                                                         brother->_col = BLACK;
  565.                                                         RotateR(delParentPos);
  566.                                                         //需要继续处理
  567.                                                         brother = delParentPos->_left; //更新brother(否则在本循环中执行其他情况的代码会出错)
  568.                                                 }
  569.                                                 //情况二:brother为黑色,且其左右孩子都是黑色结点或为空
  570.                                                 if (((brother->_left == nullptr) || (brother->_left->_col == BLACK))
  571.                                                         && ((brother->_right == nullptr) || (brother->_right->_col == BLACK)))
  572.                                                 {
  573.                                                         brother->_col = RED;
  574.                                                         if (delParentPos->_col == RED)
  575.                                                         {
  576.                                                                 delParentPos->_col = BLACK;
  577.                                                                 break;
  578.                                                         }
  579.                                                         //需要继续处理
  580.                                                         delPos = delParentPos;
  581.                                                         delParentPos = delPos->_parent;
  582.                                                 }
  583.                                                 else
  584.                                                 {
  585.                                                         //情况三:brother为黑色,且其右孩子是红色结点,左孩子是黑色结点或为空
  586.                                                         if ((brother->_left == nullptr) || (brother->_left->_col == BLACK))
  587.                                                         {
  588.                                                                 brother->_right->_col = BLACK;
  589.                                                                 brother->_col = RED;
  590.                                                                 RotateL(brother);
  591.                                                                 //需要继续处理
  592.                                                                 brother = delParentPos->_left; //更新brother(否则执行下面情况四的代码会出错)
  593.                                                         }
  594.                                                         //情况四:brother为黑色,且其左孩子是红色结点
  595.                                                         brother->_col = delParentPos->_col;
  596.                                                         delParentPos->_col = BLACK;
  597.                                                         brother->_left->_col = BLACK;
  598.                                                         RotateR(delParentPos);
  599.                                                         break; //情况四执行完毕后调整一定结束
  600.                                                 }
  601.                                         }
  602.                                 }
  603.                         }
  604.                 }
  605.                 //进行实际删除
  606.                 if (del->_left == nullptr) //实际删除结点的左子树为空
  607.                 {
  608.                         if (del == delP->_left) //实际删除结点是其父结点的左孩子
  609.                         {
  610.                                 delP->_left = del->_right;
  611.                                 if (del->_right)
  612.                                         del->_right->_parent = delP;
  613.                         }
  614.                         else //实际删除结点是其父结点的右孩子
  615.                         {
  616.                                 delP->_right = del->_right;
  617.                                 if (del->_right)
  618.                                         del->_right->_parent = delP;
  619.                         }
  620.                 }
  621.                 else //实际删除结点的右子树为空
  622.                 {
  623.                         if (del == delP->_left) //实际删除结点是其父结点的左孩子
  624.                         {
  625.                                 delP->_left = del->_left;
  626.                                 if (del->_left)
  627.                                         del->_left->_parent = delP;
  628.                         }
  629.                         else //实际删除结点是其父结点的右孩子
  630.                         {
  631.                                 delP->_right = del->_left;
  632.                                 if (del->_left)
  633.                                         del->_left->_parent = delP;
  634.                         }
  635.                 }
  636.                 delete del; //实际删除结点
  637.                 return true;
  638.         }
  639.         //查找函数
  640.         const_iterator Find(const K& key) const
  641.         {
  642.                 KeyOfT kot;
  643.                 Node* cur = _root;
  644.                 while (cur)
  645.                 {
  646.                         if (key < kot(cur->_data))        //key值小于该结点的值
  647.                         {
  648.                                 cur = cur->_left;                //在该结点的左子树当中查找
  649.                         }
  650.                         else if (key > kot(cur->_data)) //key值大于该结点的值
  651.                         {
  652.                                 cur = cur->_right;                        //在该结点的右子树当中查找
  653.                         }
  654.                         else //找到了目标结点
  655.                         {
  656.                                 return const_iterator(cur); //返回该结点
  657.                         }
  658.                 }
  659.                 return end(); //查找失败
  660.         }
  661.        
  662.         void InOrder()
  663.         {
  664.                 _InOrder(_root);
  665.                 cout << endl;
  666.         }
  667.         // 根节点->当前节点这条路径的黑色节点的数量
  668.         bool Check(Node* root, int blacknum, const int refVal)
  669.         {
  670.                 if (root == nullptr)
  671.                 {
  672.                         //cout << balcknum << endl;
  673.                         if (blacknum != refVal)
  674.                         {
  675.                                 cout << "存在黑色节点数量不相等的路径" << endl;
  676.                                 return false;
  677.                         }
  678.                         return true;
  679.                 }
  680.                 if (root->_col == RED && root->_parent->_col == RED)
  681.                 {
  682.                         cout << "有连续的红色节点" << endl;
  683.                         return false;
  684.                 }
  685.                 if (root->_col == BLACK)
  686.                 {
  687.                         ++blacknum;
  688.                 }
  689.                 return Check(root->_left, blacknum, refVal)
  690.                         && Check(root->_right, blacknum, refVal);
  691.         }
  692.         bool IsBalance()
  693.         {
  694.                 if (_root == nullptr)
  695.                         return true;
  696.                 if (_root->_col == RED)
  697.                         return false;
  698.                 //参考值
  699.                 int refVal = 0;
  700.                 Node* cur = _root;
  701.                 while (cur)
  702.                 {
  703.                         if (cur->_col == BLACK)
  704.                         {
  705.                                 ++refVal;
  706.                         }
  707.                         cur = cur->_left;
  708.                 }
  709.                 int blacknum = 0;
  710.                 return Check(_root, blacknum, refVal);
  711.         }
  712.         int Height()
  713.         {
  714.                 return _Height(_root);
  715.         }
  716. private:
  717.         size_t _Size(Node* root)
  718.         {
  719.                 if (root == NULL)
  720.                         return 0;
  721.                 return _Size(root->_left)
  722.                         + _Size(root->_right) + 1;
  723.         }
  724.         int _Height(Node* root)
  725.         {
  726.                 if (root == nullptr)
  727.                         return 0;
  728.                 int leftHeight = _Height(root->_left);
  729.                 int rightHeight = _Height(root->_right);
  730.                 return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
  731.         }
  732.         void _InOrder(Node* root)
  733.         {
  734.                 if (root == nullptr)
  735.                         return;
  736.                 _InOrder(root->_left);
  737.                 cout << root->_kv.first << " ";
  738.                 _InOrder(root->_right);
  739.         }
  740.         //拷贝树
  741.         Node* _Copy(Node* root, Node* parent)
  742.         {
  743.                 if (root == nullptr)
  744.                 {
  745.                         return nullptr;
  746.                 }
  747.                 Node* copyNode = new Node(root->_data);
  748.                 copyNode->_parent = parent;
  749.                 copyNode->_left = _Copy(root->_left, copyNode);
  750.                 copyNode->_right = _Copy(root->_right, copyNode);
  751.                 return copyNode;
  752.         }
  753.         //析构函数子函数
  754.         void _Destroy(Node* root)
  755.         {
  756.                 if (root == nullptr)
  757.                 {
  758.                         return;
  759.                 }
  760.                 _Destroy(root->_left);
  761.                 _Destroy(root->_right);
  762.                 delete root;
  763.         }
  764.         //左单旋
  765.         void RotateL(Node* parent)
  766.         {
  767.                 Node* subR = parent->_right;
  768.                 Node* subRL = subR->_left;
  769.                 Node* parentParent = parent->_parent;
  770.                 //建立subRL与parent之间的联系
  771.                 parent->_right = subRL;
  772.                 if (subRL)
  773.                         subRL->_parent = parent;
  774.                 //建立parent与subR之间的联系
  775.                 subR->_left = parent;
  776.                 parent->_parent = subR;
  777.                 //建立subR与parentParent之间的联系
  778.                 if (parentParent == nullptr)
  779.                 {
  780.                         _root = subR;
  781.                         _root->_parent = nullptr;
  782.                 }
  783.                 else
  784.                 {
  785.                         if (parent == parentParent->_left)
  786.                         {
  787.                                 parentParent->_left = subR;
  788.                         }
  789.                         else
  790.                         {
  791.                                 parentParent->_right = subR;
  792.                         }
  793.                         subR->_parent = parentParent;
  794.                 }
  795.         }
  796.         //右单旋
  797.         void RotateR(Node* parent)
  798.         {
  799.                 Node* subL = parent->_left;
  800.                 Node* subLR = subL->_right;
  801.                 Node* parentParent = parent->_parent;
  802.                 //建立subLR与parent之间的联系
  803.                 parent->_left = subLR;
  804.                 if (subLR)
  805.                         subLR->_parent = parent;
  806.                 //建立parent与subL之间的联系
  807.                 subL->_right = parent;
  808.                 parent->_parent = subL;
  809.                 //建立subL与parentParent之间的联系
  810.                 if (parentParent == nullptr)
  811.                 {
  812.                         _root = subL;
  813.                         _root->_parent = nullptr;
  814.                 }
  815.                 else
  816.                 {
  817.                         if (parent == parentParent->_left)
  818.                         {
  819.                                 parentParent->_left = subL;
  820.                         }
  821.                         else
  822.                         {
  823.                                 parentParent->_right = subL;
  824.                         }
  825.                         subL->_parent = parentParent;
  826.                 }
  827.         }
  828.         //左右双旋
  829.         void RotateLR(Node* parent)
  830.         {
  831.                 RotateL(parent->_left);
  832.                 RotateR(parent);
  833.         }
  834.         //右左双旋
  835.         void RotateRL(Node* parent)
  836.         {
  837.                 RotateR(parent->_right);
  838.                 RotateL(parent);
  839.         }
  840.         Node* _root; //红黑树的根结点       
  841. };
复制代码
正向迭代器的代码

  1. // 红黑树正向迭代器模板
  2. // 模板参数:
  3. //   T    - 结点数据类型
  4. //   Ref  - 数据的引用类型
  5. //   Ptr  - 数据的指针类型
  6. template<class T, class Ref, class Ptr>
  7. struct __TreeIterator
  8. {
  9.     typedef Ref reference;    // 数据引用类型定义
  10.     typedef Ptr pointer;      // 数据指针类型定义
  11.     typedef RBTreeNode<T> Node;          // 红黑树结点类型
  12.     typedef __TreeIterator<T, Ref, Ptr> Self;  // 迭代器自身类型
  13.     Node* _node;  // 当前迭代器持有的结点指针
  14.     // 构造函数
  15.     // 参数:
  16.     //   node - 需要包装的结点指针
  17.     __TreeIterator(Node* node)
  18.         : _node(node)  // 初始化持有的结点指针
  19.     {}
  20.     // 解引用操作符(获取数据引用)
  21.     Ref operator*()
  22.     {
  23.         return _node->_data;  // 返回结点存储数据的引用
  24.     }
  25.     // 箭头操作符(获取数据指针)
  26.     Ptr operator->()
  27.     {
  28.         return &_node->_data;  // 返回指向结点数据的指针
  29.     }
  30.     // 不等比较操作符
  31.     // 参数:
  32.     //   s - 要比较的迭代器
  33.     // 返回值: 两个迭代器是否指向不同结点
  34.     bool operator!=(const Self& s) const
  35.     {
  36.         return _node != s._node;  // 直接比较结点指针
  37.     }
  38.     // 相等比较操作符
  39.     // 参数:
  40.     //   s - 要比较的迭代器
  41.     // 返回值: 两个迭代器是否指向相同结点
  42.     bool operator==(const Self& s) const
  43.     {
  44.         return _node == s._node;  // 直接比较结点指针
  45.     }
  46.     // 前置自增操作符(中序遍历顺序的下一个结点)
  47.     Self operator++()
  48.     {
  49.         if (_node->_right)  // 当前结点存在右子树
  50.         {
  51.             // 寻找右子树的最左结点(右子树中的最小结点)
  52.             Node* left = _node->_right;
  53.             while (left->_left)
  54.             {
  55.                 left = left->_left;
  56.             }
  57.             _node = left;
  58.         }
  59.         else  // 当前结点没有右子树
  60.         {
  61.             // 向上寻找第一个不是右孩子的祖先结点
  62.             Node* cur = _node;
  63.             Node* parent = cur->_parent;
  64.             
  65.             // 沿着父指针向上查找,直到当前结点是父结点的左孩子
  66.             while (parent && cur == parent->_right)
  67.             {
  68.                 cur = parent;
  69.                 parent = parent->_parent;
  70.             }
  71.             _node = parent;  // 最终定位到的父结点即为后继
  72.         }
  73.         return *this;
  74.     }
  75.     // 前置自减操作符(中序遍历顺序的前一个结点)
  76.     Self operator--()
  77.     {
  78.         if (_node->_left)  // 当前结点存在左子树
  79.         {
  80.             // 寻找左子树的最右结点(左子树中的最大结点)
  81.             Node* right = _node->_left;
  82.             while (right->_right)
  83.             {
  84.                 right = right->_right;
  85.             }
  86.             _node = right;
  87.         }
  88.         else  // 当前结点没有左子树
  89.         {
  90.             // 向上寻找第一个不是左孩子的祖先结点
  91.             Node* cur = _node;
  92.             Node* parent = cur->_parent;
  93.             
  94.             // 沿着父指针向上查找,直到当前结点是父结点的右孩子
  95.             while (parent && cur == parent->_left)
  96.             {
  97.                 cur = parent;
  98.                 parent = parent->_parent;
  99.             }
  100.             _node = parent;  // 最终定位到的父结点即为前驱
  101.         }
  102.         return *this;
  103.     }
  104. };
复制代码
反向迭代器的代码

  1. //反向迭代器---迭代器适配器
  2. template<class Iterator>
  3. struct ReverseIterator
  4. {
  5.         typedef ReverseIterator<Iterator> Self; //反向迭代器的类型
  6.         typedef typename Iterator::reference Ref; //结点指针的引用
  7.         typedef typename Iterator::pointer Ptr; //结点指针
  8.         Iterator _it; //反向迭代器所封装的正向迭代器
  9.         //构造函数
  10.         ReverseIterator(Iterator it)
  11.                 :_it(it) //根据所给正向迭代器构造一个反向迭代器
  12.         {}
  13.         Ref operator*()
  14.         {
  15.                 return *_it; //通过调用正向迭代器的operator*返回结点数据的引用
  16.         }
  17.         Ptr operator->()
  18.         {
  19.                 return _it.operator->(); //通过调用正向迭代器的operator->返回结点数据的指针
  20.         }
  21.         //前置++
  22.         Self& operator++()
  23.         {
  24.                 --_it; //调用正向迭代器的前置--
  25.                 return *this;
  26.         }
  27.         //前置--
  28.         Self& operator--()
  29.         {
  30.                 ++_it; //调用正向迭代器的前置++
  31.                 return *this;
  32.         }
  33.         bool operator!=(const Self& s) const
  34.         {
  35.                 return _it != s._it; //调用正向迭代器的operator!=
  36.         }
  37.         bool operator==(const Self& s) const
  38.         {
  39.                 return _it == s._it; //调用正向迭代器的operator==
  40.         }
  41. };
复制代码
set的模拟实现

成员函数功能insert插入指定元素erase删除指定元素find查找指定元素size获取容器中元素的个数empty判定容器是否为空clear清空容器swap交换两个容器中的数据count获取容器中指定元素值的元素个数
  1. #pragma once
  2. #include"RBTree.h"
  3. namespace wh
  4. {
  5.         template<class K>
  6.         class set
  7.         {
  8.         public:
  9.                 struct SetKeyOfT
  10.                 {
  11.                         const K& operator()(const K& key)
  12.                         {
  13.                                 return key;
  14.                         }
  15.                 };
  16.                
  17.                 typedef typename RBTree<K, K, SetKeyOfT>::iterator iterator;                        //正向迭代器
  18.                 typedef typename RBTree<K, K, SetKeyOfT>::const_iterator const_iterator;
  19.                 typedef typename RBTree<K, K, SetKeyOfT>::reverse_iterator reverse_iterator; //反向迭代器
  20.                 typedef typename RBTree<K, K, SetKeyOfT>::const_reverse_iterator const_reverse_iterator; //反向迭代器
  21.                 iterator begin()
  22.                 {
  23.                         return _t.begin();
  24.                 }
  25.                 iterator end()
  26.                 {
  27.                         return _t.end();
  28.                 }
  29.                 const_iterator begin() const
  30.                 {
  31.                         return _t.begin();
  32.                 }
  33.                 const_iterator end() const
  34.                 {
  35.                         return _t.end();
  36.                 }
  37.                 // 获取反向起始迭代器(指向最后一个元素)
  38.                 reverse_iterator rbegin()
  39.                 {
  40.                         return _t.rbegin();
  41.                 }
  42.                 // 获取反向结束迭代器(指向起始哨兵节点)
  43.                 reverse_iterator rend()
  44.                 {
  45.                         return _t.rend();
  46.                 }
  47.                 // 获取反向起始迭代器(指向最后一个元素)
  48.                 const_reverse_iterator rbegin() const
  49.                 {
  50.                         return _t.rbegin();
  51.                 }
  52.                 // 获取反向结束迭代器(指向起始哨兵节点)
  53.                 const_reverse_iterator rend() const
  54.                 {
  55.                         return _t.rend();
  56.                 }
  57.                 pair<iterator, bool> insert(const K& key)
  58.                 {
  59.                         return _t.Insert(key);
  60.                 }
  61.                 // 删除函数
  62.                 void erase(const K& key)
  63.                 {
  64.                         _t.Erase(key);
  65.                 }
  66.                 // 查找函数
  67.                 const_iterator find(const K& key) const
  68.                 {
  69.                         return _t.Find(key);
  70.                 }
  71.                 // 获取容器中元素的个数
  72.                 size_t size()
  73.                 {
  74.                         return _t.Size();
  75.                 }
  76.                 // 获取容器中指定元素值的元素个数
  77.                 size_t count(const K& key) const
  78.                 {
  79.                         return _t.Find(key) != _t.end() ? 1 : 0;
  80.                 }
  81.                 // 判断容器是否为空
  82.                 bool empty() const
  83.                 {
  84.                         return _t.Empty();
  85.                 }
  86.                 // 清空容器
  87.                 void clear()
  88.                 {
  89.                         _t.Clear();
  90.                 }
  91.                 void swap(set& other)
  92.                 {
  93.                         _t.Swap(other._t);
  94.                 }
  95.         private:
  96.                 RBTree<K, K, SetKeyOfT> _t;
  97.         };
  98. }
复制代码
map的模拟实现

接口分类接口名称作用插入操纵insert插入键值对,返回插入效果(迭代器 + 是否成功)。emplace原地构造键值对,制止暂时对象拷贝。operator[]通过键访问值(若键不存在,插入默认值并返回引用)。删除操纵erase删除指定键或迭代器范围内的键值对。clear清空全部键值对。查找与访问find查找键,返回迭代器(未找到返回 end())。count返回键的数量(0 或 1)。contains (C++20)查抄键是否存在,返回布尔值。at安全访问值(键不存在时抛出非常)。容量查询empty查抄容器是否为空。size返回键值对数量。迭代器begin / end获取正向迭代器(按键升序)。rbegin / rend获取反向迭代器(按键降序)。
  1. #pragma once
  2. #include"RBTree.h"
  3. namespace wh
  4. {
  5.         template<class K, class V>
  6.         class map
  7.         {
  8.         public:
  9.                 struct MapKeyOfT
  10.                 {
  11.                         const K& operator()(const pair<K, V>& kv)
  12.                         {
  13.                                 return kv.first;
  14.                         }
  15.                 };
  16.                 // 对类模板取内嵌类型,加typename告诉编译器这里是类型
  17.                 typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::iterator iterator;
  18.                 typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::const_iterator const_iterator;
  19.                 typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::reverse_iterator reverse_iterator;
  20.                 typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::const_reverse_iterator const_reverse_iterator;
  21.         // 获取起始迭代器(指向第一个元素)
  22.         iterator begin()
  23.         {
  24.             return _t.begin();
  25.         }
  26.         // 获取结束迭代器(指向末尾哨兵节点)
  27.         iterator end()
  28.         {
  29.             return _t.end();
  30.         }
  31.         // 获取起始迭代器(指向第一个元素)
  32.         const_iterator begin() const
  33.         {
  34.             return _t.begin();
  35.         }
  36.         // 获取结束迭代器(指向末尾哨兵节点)
  37.         const_iterator end() const
  38.         {
  39.             return _t.end();
  40.         }
  41.         // 获取反向起始迭代器(指向最后一个元素)
  42.         reverse_iterator rbegin()
  43.         {
  44.             return _t.rbegin();
  45.         }
  46.         // 获取反向结束迭代器(指向起始哨兵节点)
  47.         reverse_iterator rend()
  48.         {
  49.             return _t.rend();
  50.         }
  51.         // 获取反向起始迭代器(指向最后一个元素)
  52.         const_reverse_iterator rbegin() const
  53.         {
  54.             return _t.rbegin();
  55.         }
  56.         // 获取反向结束迭代器(指向起始哨兵节点)
  57.         const_reverse_iterator rend() const
  58.         {
  59.             return _t.rend();
  60.         }
  61.         // 插入键值对
  62.         // 参数: kv - 要插入的键值对
  63.         // 返回值: 包含迭代器和插入结果的 pair
  64.         pair<iterator, bool> insert(const pair<const K, V>& kv)
  65.         {
  66.             return _t.Insert(kv);
  67.         }
  68.         // 下标访问运算符重载
  69.         // 参数: key - 要访问的键
  70.         // 返回值: 对应值的引用(若键不存在则自动插入默认值)
  71.         V& operator[](const K& key)
  72.         {
  73.             // 尝试插入键值对(若存在则获取已存在的元素)
  74.             pair<iterator, bool> ret = insert(make_pair(key, V()));
  75.             iterator it = ret.first;     // 获取迭代器
  76.             return it->second;            // 返回值的引用
  77.         }
  78.         // 删除指定键的元素
  79.         // 参数: key - 要删除的键
  80.         void erase(const K& key)
  81.         {
  82.             _t.Erase(key);
  83.         }
  84.         // 查找指定键的元素
  85.         // 参数: key - 要查找的键
  86.         // 返回值: 指向元素的迭代器(若未找到则返回 end())
  87.         iterator find(const K& key)
  88.         {
  89.             return _t.Find(key);
  90.         }
  91.                 // 获取容器中元素的个数
  92.                 size_t size()
  93.                 {
  94.                         return _t.Size();
  95.                 }
  96.                 // 获取容器中指定元素值的元素个数
  97.                 size_t count(const K& key) const
  98.                 {
  99.                         return _t.Find(key) != _t.end() ? 1 : 0;
  100.                 }
  101.                 // 判断容器是否为空
  102.                 bool empty() const
  103.                 {
  104.                         return _t.Empty();
  105.                 }
  106.                 // 清空容器
  107.                 void clear()
  108.                 {
  109.                         _t.Clear();
  110.                 }
  111.         private:
  112.                 RBTree<K, pair<const K, V>, MapKeyOfT> _t;
  113.         };
  114. }
复制代码


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

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

自由的羽毛

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表