• 【C++】STL —— map和set的模拟实现


    目录

    一、基础铺垫

    二、基本结构分析

    1. 节点结构分析 

    2. 模板参数中仿函数分析

    三、正向迭代器

    四、封装完成的红黑树

    五、map的模拟实现

    六、set的模拟实现


    一、基础铺垫

            在前面的博客中我们了解了map和set的基本使用,以及对二叉搜索树、AVL树和红黑树的概念和简单实现有了一定的了解后,对于map和set来说,他们的底层实现都是基于红黑树的。我们知道set是key的模型、map是key/value的模型,那么一棵红黑树是如何实现出map和set的呢?

    二、基本结构分析

    1. 节点结构分析 

            以上是截取的部分源码结构,我们可以看到set的模板参数是Key,map的模板参数是KeyT;set将Key这个模板参数typedef成了key_type和value_type,map将Key这个模板参数typedef成了key_type、将T这个模板参数typedef成了data_type;

            他们同时调用红黑树时,都是用的value_type,对应set的value_type是Key,对应map的value_type是pair;这意味着红黑树只看传过来的value_type是什么类型的,当上层容器是set的时候,结点当中存储的是键值Key;当上层容器是map的时候,结点当中存储的就是键值对。

    结点结构: 

    1. enum Colour
    2. {
    3. RED,
    4. BLACK
    5. };
    6. template<class T>
    7. struct RBTreeNode
    8. {
    9. RBTreeNode* _left;
    10. RBTreeNode* _right;
    11. RBTreeNode* _parent;
    12. T _data;//存储的数据类型:如果是set,T对应的就是K;如果是map,T对应的就是pair
    13. Colour _col;
    14. RBTreeNode(const T& data)
    15. :_left(nullptr)
    16. , _right(nullptr)
    17. , _parent(nullptr)
    18. , _col(RED)
    19. , _data(data)
    20. {}
    21. };

    红黑树基本结构: 

    1. template<class k, class T>
    2. class RBTree
    3. {
    4. typedef RBTreeNode Node;
    5. private:
    6. Node* _root;
    7. };

    map的基本结构: 

    1. namespace mlg
    2. {
    3. template<class k, class v>
    4. class map
    5. {
    6. private:
    7. RBTree> _t;
    8. };
    9. }

    set的基本结构: 

    1. namespace mlg
    2. {
    3. template<class k>
    4. class set
    5. {
    6. private:
    7. RBTree _t;
    8. };
    9. }

    2. 模板参数中仿函数分析

            因为红黑树中存储的是T类型,有可能是Key,也有可能是键值对;那么当我们需要进行结点的键值比较时,应该如何获取结点的键值呢?

            当上层容器是set的时候T就是键值Key,直接用T进行比较即可,但当上层容器是map的时候就不行了,此时我们需要从键值对当中取出键值Key后,再用Key值进行比较。

            因此,上层容器map需要向底层红黑树提供一个仿函数,用于获取T当中的键值Key,这样一来,当底层红黑树当中需要比较两个结点的键值时,就可以通过这个仿函数来获取T当中的键值了。

    map的仿函数:

    1. namespace mlg
    2. {
    3. template<class k, class v>
    4. class map
    5. {
    6. public:
    7. struct MapKeyOfT
    8. {
    9. const k& operator()(const pair& kv)
    10. {
    11. return kv.first;
    12. }
    13. };
    14. private:
    15. RBTree, MapKeyOfT> _t;
    16. };
    17. }

    set的仿函数:

    1. namespace mlg
    2. {
    3. template<class k>
    4. class set
    5. {
    6. public:
    7. struct SetKeyOfT
    8. {
    9. const k& operator()(const k& k)
    10. {
    11. return k;
    12. }
    13. };
    14. private:
    15. RBTree _t;
    16. };
    17. }

    三、正向迭代器

            红黑树的正向迭代器实际上就是对结点指针进行了封装,因此在正向迭代器当中实际上就只有一个成员变量,那就是正向迭代器所封装结点的指针。 

    1. template<class T, class Ref, class Ptr>
    2. struct RBTreeIterator
    3. {
    4. typedef RBTreeNode Node;//结点的类型
    5. typedef RBTreeIterator Self;//正向迭代器的类型
    6. Node* _node;//正向迭代器所封装结点的指针
    7. RBTreeIterator(Node* node)//根据所给结点指针构造一个正向迭代器
    8. :_node(node)
    9. {}
    10. Ref operator*()
    11. {
    12. return _node->_data;//返回结点数据的引用
    13. }
    14. Ptr operator->()
    15. {
    16. return &_node->_data;//返回结点数据的指针
    17. }
    18. //前置++
    19. /*
    20. 如果当前结点的右子树不为空,则++操作后应该找到其右子树当中的最左结点。
    21. 如果当前结点的右子树为空,则++操作后应该在该结点的祖先结点中,找到孩子不在父亲右的祖先。
    22. */
    23. Self& operator++()
    24. {
    25. if (_node->_right)//结点的右子树不为空
    26. {
    27. Node* min = _node->_right;
    28. while (min->_left)
    29. {
    30. min = min->_left;
    31. }
    32. _node = min;
    33. }
    34. else //结点的右子树为空
    35. {
    36. Node* cur = _node;
    37. Node* parent = cur->_parent;
    38. while (parent && cur == parent->_right)
    39. {
    40. cur = cur->_parent;
    41. parent = parent->_parent;
    42. }
    43. _node = parent;
    44. }
    45. return *this;
    46. }
    47. //前置--
    48. /*
    49. 如果当前结点的左子树不为空,则--操作后应该找到其左子树当中的最右结点。
    50. 如果当前结点的左子树为空,则--操作后应该在该结点的祖先结点中,找到孩子不在父亲左的祖先。
    51. */
    52. Self& operator--()
    53. {
    54. if (_node->_left)
    55. {
    56. Node* max = _node->_left;
    57. while (max->_right)
    58. {
    59. max = max->_right;
    60. }
    61. _node = max;
    62. }
    63. else
    64. {
    65. Node* cur = _node;
    66. Node* parent = cur->_parent;
    67. while (parent && cur == parent->_left)
    68. {
    69. cur = parent;
    70. parent = parent->_parent;
    71. }
    72. _node = parent;
    73. }
    74. return *this;
    75. }
    76. //判断两个正向迭代器是否不同
    77. bool operator!=(const Self& s)const
    78. {
    79. return _node != s._node;
    80. }
    81. //判断两个正向迭代器是否相同
    82. bool operator==(const Self& s)const
    83. {
    84. return _node == s._node;
    85. }
    86. };

    四、封装完成的红黑树

    1. #pragma once
    2. #include
    3. #include
    4. using namespace std;
    5. enum Colour
    6. {
    7. RED,
    8. BLACK
    9. };
    10. template<class T>
    11. struct RBTreeNode
    12. {
    13. RBTreeNode* _left;
    14. RBTreeNode* _right;
    15. RBTreeNode* _parent;
    16. T _data;
    17. Colour _col;
    18. RBTreeNode(const T& data)
    19. :_left(nullptr)
    20. , _right(nullptr)
    21. , _parent(nullptr)
    22. , _col(RED)
    23. , _data(data)
    24. {}
    25. };
    26. template<class T, class Ref, class Ptr>
    27. struct RBTreeIterator
    28. {
    29. typedef RBTreeNode Node;
    30. typedef RBTreeIterator Self;
    31. Node* _node;
    32. RBTreeIterator(Node* node)
    33. :_node(node)
    34. {}
    35. Ref operator*()
    36. {
    37. return _node->_data;
    38. }
    39. Ptr operator->()
    40. {
    41. return &_node->_data;
    42. }
    43. //前置++
    44. Self& operator++()
    45. {
    46. if (_node->_right)
    47. {
    48. Node* min = _node->_right;
    49. while (min->_left)
    50. {
    51. min = min->_left;
    52. }
    53. _node = min;
    54. }
    55. else
    56. {
    57. Node* cur = _node;
    58. Node* parent = cur->_parent;
    59. while (parent && cur == parent->_right)
    60. {
    61. cur = cur->_parent;
    62. parent = parent->_parent;
    63. }
    64. _node = parent;
    65. }
    66. return *this;
    67. }
    68. //前置--
    69. Self& operator--()
    70. {
    71. if (_node->_left)
    72. {
    73. Node* max = _node->_left;
    74. while (max->_right)
    75. {
    76. max = max->_right;
    77. }
    78. _node = max;
    79. }
    80. else
    81. {
    82. Node* cur = _node;
    83. Node* parent = cur->_parent;
    84. while (parent && cur == parent->_left)
    85. {
    86. cur = parent;
    87. parent = parent->_parent;
    88. }
    89. _node = parent;
    90. }
    91. return *this;
    92. }
    93. bool operator!=(const Self& s)const
    94. {
    95. return _node != s._node;
    96. }
    97. bool operator==(const Self& s)const
    98. {
    99. return _node == s._node;
    100. }
    101. };
    102. //set RBTree
    103. //map RBTree>
    104. template<class k, class T, class keyofT>
    105. class RBTree
    106. {
    107. typedef RBTreeNode Node;
    108. public:
    109. typedef RBTreeIterator iterator;
    110. typedef RBTreeIteratorconst T&, const T*> const_iterator;
    111. iterator begin()
    112. {
    113. Node* min = _root;
    114. while (min && min->_left)
    115. {
    116. min = min->_left;
    117. }
    118. return iterator(min);
    119. }
    120. iterator end()
    121. {
    122. return iterator(nullptr);
    123. }
    124. RBTree()
    125. :_root(nullptr)
    126. {}
    127. RBTree(const RBTree& t)
    128. {
    129. _root = Copy(t._root);
    130. }
    131. Node* Copy(Node* root)
    132. {
    133. if (root == nullptr)
    134. {
    135. return nullptr;
    136. }
    137. Node* newRoot = new Node(root->_data);
    138. newRoot->_col = root->_col;
    139. newRoot->_left = Copy(root->_left);
    140. newRoot->_right = Copy(root->_right);
    141. if (newRoot->_left)
    142. {
    143. newRoot->_left->_parent = newRoot;
    144. }
    145. if (newRoot->_right)
    146. {
    147. newRoot->_right->_parent = newRoot;
    148. }
    149. return newRoot;
    150. }
    151. RBTree& operator=(RBTree t)
    152. {
    153. swap(_root, t._root);
    154. return *this;
    155. }
    156. ~RBTree()
    157. {
    158. Destroy(_root);
    159. _root = nullptr;
    160. }
    161. void Destroy(Node* root)
    162. {
    163. if (root == nullptr)
    164. {
    165. return;
    166. }
    167. Destroy(root->_left);
    168. Destroy(root->_right);
    169. delete root;
    170. }
    171. iterator Find(const k& key)
    172. {
    173. Node* cur = _root;
    174. keyofT kot;
    175. while (cur)
    176. {
    177. if (kot(cur->_data) < key)
    178. {
    179. cur = cur->_right;
    180. }
    181. else if (kot(cur->_data) > key)
    182. {
    183. cur = cur->_left;
    184. }
    185. else
    186. {
    187. return iterator(cur);
    188. }
    189. }
    190. return end();
    191. }
    192. pairbool> Insert(const T& data)
    193. {
    194. if (_root == nullptr)
    195. {
    196. _root = new Node(data);
    197. _root->_col = BLACK;
    198. return make_pair(iterator(_root), true);
    199. }
    200. keyofT kot;
    201. Node* parent = nullptr;
    202. Node* cur = _root;
    203. while (cur)
    204. {
    205. if (kot(cur->_data) < kot(data))
    206. {
    207. parent = cur;
    208. cur = cur->_right;
    209. }
    210. else if (kot(cur->_data) > kot(data))
    211. {
    212. parent = cur;
    213. cur = cur->_left;
    214. }
    215. else
    216. {
    217. return make_pair(iterator(cur), false);
    218. }
    219. }
    220. cur = new Node(data);
    221. Node* newnode = cur;
    222. cur->_col = RED; // 新增节点
    223. if (kot(parent->_data) < kot(data))
    224. {
    225. parent->_right = cur;
    226. cur->_parent = parent;
    227. }
    228. else
    229. {
    230. parent->_left = cur;
    231. cur->_parent = parent;
    232. }
    233. // 控制平衡
    234. while (parent && parent->_col == RED)
    235. {
    236. Node* grandfather = parent->_parent;
    237. if (parent == grandfather->_left)
    238. {
    239. Node* uncle = grandfather->_right;
    240. // 1、uncle存在且为红
    241. if (uncle && uncle->_col == RED)
    242. {
    243. // 变色+继续向上处理
    244. parent->_col = uncle->_col = BLACK;
    245. grandfather->_col = RED;
    246. cur = grandfather;
    247. parent = cur->_parent;
    248. }
    249. else // 2 + 3、uncle不存在/ 存在且为黑
    250. {
    251. if (cur == parent->_left)
    252. {
    253. // 单旋
    254. RotateR(grandfather);
    255. parent->_col = BLACK;
    256. grandfather->_col = RED;
    257. }
    258. else
    259. {
    260. // 双旋
    261. RotateL(parent);
    262. RotateR(grandfather);
    263. cur->_col = BLACK;
    264. grandfather->_col = RED;
    265. }
    266. break;
    267. }
    268. }
    269. else // parent == grandfather->_right
    270. {
    271. Node* uncle = grandfather->_left;
    272. if (uncle && uncle->_col == RED)
    273. {
    274. // 变色+继续向上处理
    275. parent->_col = uncle->_col = BLACK;
    276. grandfather->_col = RED;
    277. cur = grandfather;
    278. parent = cur->_parent;
    279. }
    280. else // 2 + 3、uncle不存在/ 存在且为黑
    281. {
    282. if (cur == parent->_right)
    283. {
    284. RotateL(grandfather);
    285. parent->_col = BLACK;
    286. grandfather->_col = RED;
    287. }
    288. else
    289. {
    290. RotateR(parent);
    291. RotateL(grandfather);
    292. cur->_col = BLACK;
    293. grandfather->_col = RED;
    294. }
    295. break;
    296. }
    297. }
    298. }
    299. _root->_col = BLACK;
    300. return make_pair(iterator(newnode), true);
    301. }
    302. //左单选
    303. void RotateL(Node* parent)
    304. {
    305. Node* subR = parent->_right;
    306. Node* subRL = subR->_left;
    307. parent->_right = subRL;
    308. if (subRL)
    309. {
    310. subRL->_parent = parent;
    311. }
    312. Node* parentParent = parent->_parent;
    313. subR->_left = parent;
    314. parent->_parent = subR;
    315. if (parent == _root)//这里表明原来是根
    316. {
    317. _root = subR;
    318. subR->_parent = nullptr;
    319. }
    320. else
    321. {
    322. if (parentParent->_left == parent)
    323. {
    324. parentParent->_left = subR;
    325. }
    326. else
    327. {
    328. parentParent->_right = subR;
    329. }
    330. subR->_parent = parentParent;
    331. }
    332. }
    333. //由单旋
    334. void RotateR(Node* parent)
    335. {
    336. Node* subL = parent->_left;
    337. Node* subLR = subL->_right;
    338. parent->_left = subLR;
    339. if (subLR)
    340. {
    341. subLR->_parent = parent;
    342. }
    343. Node* parentParent = parent->_parent;
    344. subL->_right = parent;
    345. parent->_parent = subL;
    346. if (parent == _root)//这里表明原来是根
    347. {
    348. _root = subL;
    349. _root->_parent = nullptr;
    350. }
    351. else
    352. {
    353. if (parentParent->_left == parent)
    354. {
    355. parentParent->_left = subL;
    356. }
    357. else
    358. {
    359. parentParent->_right = subL;
    360. }
    361. subL->_parent = parentParent;
    362. }
    363. }
    364. void InOrder()
    365. {
    366. _InOrder(_root);
    367. }
    368. void _InOrder(Node* root)
    369. {
    370. if (root == nullptr)
    371. {
    372. return;
    373. }
    374. _InOrder(root->_left);
    375. cout << root->_kv.first << ":" << root->_kv.second << endl;
    376. _InOrder(root->_right);
    377. }
    378. private:
    379. Node* _root;
    380. };

    五、map的模拟实现

    1. #include "RBTree.h"
    2. namespace mlg
    3. {
    4. template<class k, class v>
    5. class map
    6. {
    7. public:
    8. struct MapKeyOfT
    9. {
    10. const k& operator()(const pair& kv)
    11. {
    12. return kv.first;
    13. }
    14. };
    15. typedef typename RBTree, MapKeyOfT>::iterator iterator;
    16. iterator begin()
    17. {
    18. return _t.begin();
    19. }
    20. iterator end()
    21. {
    22. return _t.end();
    23. }
    24. pairbool> insert(const pair& kv)
    25. {
    26. return _t.Insert(kv);
    27. }
    28. iterator find(const k& key)
    29. {
    30. return _t.Find(key);
    31. }
    32. v& operator[](const k& key)
    33. {
    34. auto ret = _t.Insert(make_pair(key, v()));
    35. return ret.first->second;
    36. }
    37. private:
    38. RBTree, MapKeyOfT> _t;
    39. };
    40. }

    六、set的模拟实现

    1. #include "RBTree.h"
    2. namespace mlg
    3. {
    4. template<class k>
    5. class set
    6. {
    7. public:
    8. struct SetKeyOfT
    9. {
    10. const k& operator()(const k& k)
    11. {
    12. return k;
    13. }
    14. };
    15. typedef typename RBTree::iterator iterator;
    16. iterator begin()
    17. {
    18. return _t.begin();
    19. }
    20. iterator end()
    21. {
    22. return _t.end();
    23. }
    24. pairbool> insert(const k& key)
    25. {
    26. return _t.Insert(key);
    27. }
    28. iterator find(const k& key)
    29. {
    30. return _t.Find(key);
    31. }
    32. private:
    33. RBTree _t;
    34. };
    35. }

  • 相关阅读:
    DPDK ACL算法介绍(一)
    基于Jsp+Servlet+MySql的汉服网站的设计与实现-源码+毕业论文
    [漏洞复现] jenkins 远程代码执行 (CVE-2019-100300)
    PyCharm安装PyQt5及其工具(Qt Designer、PyUIC、PyRcc)详细教程
    Kruskal,346. 走廊泼水节
    枚举类与注解(复习)
    WebRTC REMB 算法
    vue.config.js 配置proxy代理
    HiEV独家 | 接棒余承东,华为光产品线总裁靳玉志出任车BU CEO
    数据分析:单元2 NumPy数据存取与函数
  • 原文地址:https://blog.csdn.net/sjsjnsjnn/article/details/128096084