• c++——map和set的封装


    注:该封装基于前面博客已实现红黑树,map和set封装并不难,主要还是对红黑树的理解


    目录

    一. 改造红黑树

    1. 改变节点的定义,使用更高维度的泛型

    2. 红黑树追加迭代器的实现

    1. 红黑树迭代器的构造函数和基本框架

    2. begin()和end()的实现

    3. operator*和operator->的实现

    4. operator++和operator--的实现

    5. operator!=和operator==的实现

    3. 对RBTree类进行改变

    1. 改造insert

    2. 增加find的实现

    4. 改造后的RBTree树代码展示

    二. 封装set

    三. 封装map


    一. 改造红黑树

    颜色定义不更改,但是由于我们是使用一颗红黑树同时来作为封装set和map的底层结构,因此对数据类型需要进行处理,这里参考stl源码给出的解决方式是使用更高维度的泛型,因此我们也定义成更高维度的泛型,即数据类型这里我们使用T来接受va类型。

    即我们不再使用KV的形式接受数据,而是用T来接受数据,T决定红黑树存什么数据。

    这里和节点定义一样,我们使用T来接受数据,T决定红黑树存什么数据,对于set来说RBTree传进来的是K,对于map来说RBTree>传进来的是pair类型。

    虽然用T能解决传进来不同的数据类型,但是由于我们需要取K,对于set来说K就是K,但是,对于map来说是pair的第一个参数,所以由于无法确定T是K还是pair类型,无法准确去取出来T中的类型。

    根据官方库可以发现再引进来一个模板参数KeyOfT,用来取出T中的类型,而这个KeOfT传给RBTree的,查看set和map后源码后发现KeyOfT其实是一个仿函数,用来提取T中类型的K的,因此我们就知道RBTree应该有三个模板参数,分别是K,T和KeyOfT

    1. 改变节点的定义,使用更高维度的泛型

    有了以上推论,我们可以对节点定义进行改变

    1. //改变红黑节点的定义,使用更高维度的泛型
    2. template<class T>
    3. struct RBTreeNode
    4. {
    5. RBTreeNode* _left;
    6. RBTreeNode* _right;
    7. RBTreeNode* _parent;
    8. T _data;
    9. color _col;
    10. //构造函数
    11. RBTreeNode(const T& data)
    12. :_left(nullptr)
    13. ,_right(nullptr)
    14. ,_parent(nullptr)
    15. ,_data(data)
    16. ,_col(RED)
    17. {}
    18. };

    这里使用T来标识数据类型,因为节点可能是K类型的(set传过来的),也可能是pair类型的(map传过来的)

    2. 红黑树追加迭代器的实现

    由于map和set都需要用到迭代器,但是两者的迭代器实际上都是封装了红黑树的迭代器,因此我们要先实现红黑树的迭代器,这里迭代器的实现和链表极其相似,因此,也是使用三个模板参数,分别代表普通类型,引用类型,指针类型,库里的实现是采用了哨兵卫的头节点的方式,但是这里并不这样做

    1. 红黑树迭代器的构造函数和基本框架

    1. template<class T, class Ref, class Ptr>
    2. struct __RBTreeIterator
    3. {
    4. typedef RBTreeNode Node;//方便使用节点
    5. typedef __RBTreeIterator Self;//方便使用自己
    6. Node* _node;//节点指针
    7. //迭代器构造函数
    8. __RBTreeIterator(Node* node)
    9. :_node(node)
    10. {}
    11. operator*()
    12. {}
    13. operator->()
    14. {}
    15. operator++()
    16. {}
    17. operator++(int)
    18. {}
    19. operator--()
    20. {}
    21. operator--(int)
    22. {}
    23. operator!=(const Self& s) const
    24. {}
    25. operator==(const Self& s) const
    26. {}
    27. };

    和链表迭代器的实现基本一致,将迭代器的基本功能实现

    2. begin()和end()的实现

    由于迭代器访问的顺序是按照二叉平衡搜索树的中序的顺序访问的,因此我们也不能坏这个规则。

    按中序访问的思路,左子树->根->右子树:

    begin应该返回中序的第一个元素,即需要去找二叉平衡搜索树的最左节点:

    1. iterator Begin()
    2. {
    3. Node* subleft = _root;
    4. while (subleft && subleft->_left)
    5. {
    6. subleft = subleft->_left;
    7. }
    8. return iterator(subleft);
    9. }

    由于迭代器是自己实现的类,因此应该用迭代器创建对象并返回

     end()应该返回的是nullptr,因为最后遍历完成后应该是遍历到最右节点的nullptr节点

    1. iterator End()
    2. {
    3. return iterator(nullptr);
    4. }

    直接用迭代器创建一个对象并传nullptr

    3. operator*和operator->的实现

    和链表一样,operator*返回节点中的数据operator->返回节点数据的地址(原因已在链表迭代器实现已解释,不做过多赘述)

    1. Ref operator*()
    2. {
    3. return _node->_data;
    4. }
    5. Ptr operator->()
    6. {
    7. return &_node->_data;
    8. }

    4. operator++和operator--的实现

    由于begin(),是按照中序的方式访问的,++可以分为两种情况,当右子树不存在为空时,找孩子是祖先的左的那个祖先节点,当右子树存在不为空时,找右子树的最左节点

    有如下图红黑树:

    一开始begin()迭代器应该位于节点为1处,当我们要++遍历这颗红黑树时:

    由于1的右子树不为空,找右子树的最左节点,最左节点为空,则++以后访问到是6,由于6的右子树为空,再++应该去找孩子是祖先的左的那个祖先节点,此时找到就是节点为8的祖先节点,此时发现,这就已经按中序的方式运行起来了

    ++迭代器的实现方式如下代码:

    1. Self& operator++()
    2. {
    3. if (_node->_right == nullptr)
    4. {
    5. Node* cur = _node;
    6. Node* parent = cur->_parent;
    7. while (parent && parent->_right == cur)
    8. {
    9. cur = parent;
    10. parent = parent->_parent;
    11. }
    12. _node = parent;
    13. }
    14. else
    15. {
    16. Node* subleft = _node->_right;
    17. while (subleft->_left)
    18. {
    19. subleft = subleft->_left;
    20. }
    21. _node = subleft;
    22. }
    23. return *this;
    24. }
    25. Self operator++(int)
    26. {
    27. Self tmp(*this);
    28. ++(*this);
    29. return tmp;
    30. }

    由于begin(),是按照中序的方式访问的,--可以分为两种情况,当左子树不存在为空时,找孩子是祖先的右的那个祖先节点,当左子树存在不为空时,找左子树的最右节点

    以下图红黑树为例:

    假设此时迭代器已经遍历到节点为11的地方:

    当我们要--遍历红黑树时,由于11的左子树不存在为空,往上找孩子是祖先的右的祖先节点,我发现11就是8的右,于是迭代器访问的是节点8的祖先节点,再次--,此时节点8的左子树存在不为空,找左子树的最右节点,此时节点6是1的最右节点,因此找到的节点是节点6,此时,发现已经是在按中序的方式遍历了

    --的迭代器的实现代码如下:

    1. Self& operator--()
    2. {
    3. if (_node->_left == nullptr)
    4. {
    5. // 找祖先里面,孩子是父亲
    6. Node* cur = _node;
    7. Node* parent = cur->_parent;
    8. while (parent && cur == parent->_left)
    9. {
    10. cur = cur->_parent;
    11. parent = parent->_parent;
    12. }
    13. _node = parent;
    14. }
    15. else
    16. {
    17. // 左子树的最右节点
    18. Node* subRight = _node->_left;
    19. while (subRight->_right)
    20. {
    21. subRight = subRight->_right;
    22. }
    23. _node = subRight;
    24. }
    25. return *this;
    26. }
    27. Self operator--(int)
    28. {
    29. Self tmp(*this);
    30. --(*this);
    31. return tmp;
    32. }

    5. operator!=和operator==的实现

    比两个对象中的节点即可

    1. bool operator!=(const Self& s) const
    2. {
    3. return _node != s._node;
    4. }
    5. bool operator==(const Self& s) const
    6. {
    7. return _node == s->_node;
    8. }

    至此迭代器的基本实现已完成

    3. 对RBTree类进行改变

    由于模板参数的改变和迭代器的实现,使RBTree的实现更加完整,需要对RBTree类进行改变。

    1. 改造insert

    首先就是对insert进行改变,有了迭代器的实现,我们应该和库里面的一样,返回的是pair而不是bool,以及在比较的时候应该使用KeyOfT这个仿函数模板参数来接受K,修改完成代码如下:

    1. pairbool> Insert(const T& data)
    2. {
    3. // 1、搜索树的规则插入
    4. // 2、看是否违反平衡规则,如果违反就需要处理:旋转
    5. if (_root == nullptr)
    6. {
    7. _root = new Node(data);
    8. _root->_col = BLACK;
    9. return make_pair(iterator(_root), true);
    10. }
    11. KeyOfT kot;
    12. Node* parent = nullptr;
    13. Node* cur = _root;
    14. while (cur)
    15. {
    16. if (kot(cur->_data) < kot(data))
    17. {
    18. parent = cur;
    19. cur = cur->_right;
    20. }
    21. else if (kot(cur->_data) > kot(data))
    22. {
    23. parent = cur;
    24. cur = cur->_left;
    25. }
    26. else
    27. {
    28. return make_pair(iterator(cur), true);
    29. }
    30. }
    31. cur = new Node(data);
    32. Node* newnode = cur;
    33. cur->_col = RED;
    34. if (kot(parent->_data) < kot(data))
    35. {
    36. parent->_right = cur;
    37. }
    38. else
    39. {
    40. parent->_left = cur;
    41. }
    42. cur->_parent = parent;
    43. // 存在连续红色节点
    44. while (parent && parent->_col == RED)
    45. {
    46. Node* grandfater = parent->_parent;
    47. assert(grandfater);
    48. if (grandfater->_left == parent)
    49. {
    50. Node* uncle = grandfater->_right;
    51. // 情况一:
    52. if (uncle && uncle->_col == RED) // 叔叔存在且为红
    53. {
    54. // 变色
    55. parent->_col = uncle->_col = BLACK;
    56. grandfater->_col = RED;
    57. // 继续往上处理
    58. cur = grandfater;
    59. parent = cur->_parent;
    60. }
    61. else // 叔叔不存在 或者 叔叔存在且为黑
    62. {
    63. if (cur == parent->_left) // 单旋
    64. {
    65. // g
    66. // p
    67. // c
    68. RotateR(grandfater);
    69. parent->_col = BLACK;
    70. grandfater->_col = RED;
    71. }
    72. else // 双旋
    73. {
    74. // g
    75. // p
    76. // c
    77. RotateL(parent);
    78. RotateR(grandfater);
    79. cur->_col = BLACK;
    80. grandfater->_col = RED;
    81. }
    82. break;
    83. }
    84. }
    85. else //(grandfater->_right == parent)
    86. {
    87. Node* uncle = grandfater->_left;
    88. // 情况一:
    89. if (uncle && uncle->_col == RED)
    90. {
    91. // 变色
    92. parent->_col = uncle->_col = BLACK;
    93. grandfater->_col = RED;
    94. // 继续往上处理
    95. cur = grandfater;
    96. parent = cur->_parent;
    97. }
    98. else
    99. {
    100. if (cur == parent->_right)
    101. {
    102. // g
    103. // p
    104. // c
    105. RotateL(grandfater);
    106. parent->_col = BLACK;
    107. grandfater->_col = RED;
    108. }
    109. else // 双旋
    110. {
    111. // g
    112. // p
    113. // c
    114. RotateR(parent);
    115. RotateL(grandfater);
    116. cur->_col = BLACK;
    117. grandfater->_col = RED;
    118. }
    119. break;
    120. }
    121. }
    122. }
    123. _root->_col = BLACK;
    124. return make_pair(iterator(newnode), true);//创建并返回iterator对象
    125. }

    相比原来的insert对返回值做了修改,并用KeyOfT仿函数创建对象来接受其中的K,来进行比较

    2. 增加find的实现

    利用KeyOfT提取T中的K来进行比较找想要找的元素,找到返回迭代器元素位置的迭代器否则返回end(),具体代码实现如下:

    1. iterator Find(const K& key)
    2. {
    3. Node* cur = _root;
    4. KeyOfT kot;
    5. while (cur)
    6. {
    7. if (kot(cur->_data) < key)
    8. {
    9. cur = cur->_right;
    10. }
    11. else if (kot(cur->_data) > key)
    12. {
    13. cur = cur->_left;
    14. }
    15. else
    16. {
    17. return iterator(cur);
    18. }
    19. }
    20. return End();
    21. }

    4. 改造后的RBTree树代码展示

    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; // 数据
    13. Colour _col;
    14. RBTreeNode(const T& data)
    15. :_data(data)
    16. , _left(nullptr)
    17. , _right(nullptr)
    18. , _parent(nullptr)
    19. , _col(RED)
    20. {}
    21. };
    22. template<class T, class Ref, class Ptr>
    23. struct __RBTreeIterator
    24. {
    25. typedef RBTreeNode Node;
    26. typedef __RBTreeIterator Self;
    27. Node* _node;
    28. __RBTreeIterator(Node* node)
    29. :_node(node)
    30. {}
    31. Ref operator*()
    32. {
    33. return _node->_data;
    34. }
    35. Ptr operator->()
    36. {
    37. return &_node->_data;
    38. }
    39. // 休息17:00
    40. Self& operator++()
    41. {
    42. if (_node->_right == nullptr)
    43. {
    44. // 找祖先里面,孩子是父亲左的那个
    45. Node* cur = _node;
    46. Node* parent = cur->_parent;
    47. while (parent && parent->_right == cur)
    48. {
    49. cur = cur->_parent;
    50. parent = parent->_parent;
    51. }
    52. _node = parent;
    53. }
    54. else
    55. {
    56. // 右子树的最左节点
    57. Node* subLeft = _node->_right;
    58. while (subLeft->_left)
    59. {
    60. subLeft = subLeft->_left;
    61. }
    62. _node = subLeft;
    63. }
    64. return *this;
    65. }
    66. Self operator++(int)
    67. {
    68. Self tmp(*this);
    69. ++(*this);
    70. return tmp;
    71. }
    72. Self& operator--()
    73. {
    74. if (_node->_left == nullptr)
    75. {
    76. // 找祖先里面,孩子是父亲
    77. Node* cur = _node;
    78. Node* parent = cur->_parent;
    79. while (parent && cur == parent->_left)
    80. {
    81. cur = cur->_parent;
    82. parent = parent->_parent;
    83. }
    84. _node = parent;
    85. }
    86. else
    87. {
    88. // 左子树的最右节点
    89. Node* subRight = _node->_left;
    90. while (subRight->_right)
    91. {
    92. subRight = subRight->_right;
    93. }
    94. _node = subRight;
    95. }
    96. return *this;
    97. }
    98. Self operator--(int)
    99. {
    100. Self tmp(*this);
    101. --(*this);
    102. return tmp;
    103. }
    104. bool operator!=(const Self& s) const
    105. {
    106. return _node != s._node;
    107. }
    108. bool operator==(const Self& s) const
    109. {
    110. return _node == s->_node;
    111. }
    112. };
    113. // T决定红黑树存什么数据
    114. // set RBTree
    115. // map RBTree>
    116. // KeyOfT -> 支持取出T对象中key的仿函数
    117. template<class K, class T, class KeyOfT>
    118. class RBTree
    119. {
    120. typedef RBTreeNode Node;
    121. public:
    122. typedef __RBTreeIterator iterator;
    123. typedef __RBTreeIteratorconst T&, const T*> const_iterator;
    124. // 构造 拷贝构造 赋值 和析构 跟搜索树实现方式是一样的
    125. iterator Begin()
    126. {
    127. Node* subLeft = _root;
    128. while (subLeft && subLeft->_left)
    129. {
    130. subLeft = subLeft->_left;
    131. }
    132. return iterator(subLeft);
    133. }
    134. iterator End()
    135. {
    136. return iterator(nullptr);
    137. }
    138. const_iterator Begin() const
    139. {
    140. Node* subLeft = _root;
    141. while (subLeft && subLeft->_left)
    142. {
    143. subLeft = subLeft->_left;
    144. }
    145. return const_iterator(subLeft);
    146. }
    147. const_iterator End() const
    148. {
    149. return const_iterator(nullptr);
    150. }
    151. pairbool> Insert(const T& data)
    152. {
    153. // 1、搜索树的规则插入
    154. // 2、看是否违反平衡规则,如果违反就需要处理:旋转
    155. if (_root == nullptr)
    156. {
    157. _root = new Node(data);
    158. _root->_col = BLACK;
    159. return make_pair(iterator(_root), true);
    160. }
    161. KeyOfT kot;
    162. Node* parent = nullptr;
    163. Node* cur = _root;
    164. while (cur)
    165. {
    166. if (kot(cur->_data) < kot(data))
    167. {
    168. parent = cur;
    169. cur = cur->_right;
    170. }
    171. else if (kot(cur->_data) > kot(data))
    172. {
    173. parent = cur;
    174. cur = cur->_left;
    175. }
    176. else
    177. {
    178. return make_pair(iterator(cur), true);
    179. }
    180. }
    181. cur = new Node(data);
    182. Node* newnode = cur;
    183. cur->_col = RED;
    184. if (kot(parent->_data) < kot(data))
    185. {
    186. parent->_right = cur;
    187. }
    188. else
    189. {
    190. parent->_left = cur;
    191. }
    192. cur->_parent = parent;
    193. // 存在连续红色节点
    194. while (parent && parent->_col == RED)
    195. {
    196. Node* grandfater = parent->_parent;
    197. assert(grandfater);
    198. if (grandfater->_left == parent)
    199. {
    200. Node* uncle = grandfater->_right;
    201. // 情况一:
    202. if (uncle && uncle->_col == RED) // 叔叔存在且为红
    203. {
    204. // 变色
    205. parent->_col = uncle->_col = BLACK;
    206. grandfater->_col = RED;
    207. // 继续往上处理
    208. cur = grandfater;
    209. parent = cur->_parent;
    210. }
    211. else // 叔叔不存在 或者 叔叔存在且为黑
    212. {
    213. if (cur == parent->_left) // 单旋
    214. {
    215. // g
    216. // p
    217. // c
    218. RotateR(grandfater);
    219. parent->_col = BLACK;
    220. grandfater->_col = RED;
    221. }
    222. else // 双旋
    223. {
    224. // g
    225. // p
    226. // c
    227. RotateL(parent);
    228. RotateR(grandfater);
    229. cur->_col = BLACK;
    230. grandfater->_col = RED;
    231. }
    232. break;
    233. }
    234. }
    235. else //(grandfater->_right == parent)
    236. {
    237. Node* uncle = grandfater->_left;
    238. // 情况一:
    239. if (uncle && uncle->_col == RED)
    240. {
    241. // 变色
    242. parent->_col = uncle->_col = BLACK;
    243. grandfater->_col = RED;
    244. // 继续往上处理
    245. cur = grandfater;
    246. parent = cur->_parent;
    247. }
    248. else
    249. {
    250. if (cur == parent->_right)
    251. {
    252. // g
    253. // p
    254. // c
    255. RotateL(grandfater);
    256. parent->_col = BLACK;
    257. grandfater->_col = RED;
    258. }
    259. else // 双旋
    260. {
    261. // g
    262. // p
    263. // c
    264. RotateR(parent);
    265. RotateL(grandfater);
    266. cur->_col = BLACK;
    267. grandfater->_col = RED;
    268. }
    269. break;
    270. }
    271. }
    272. }
    273. _root->_col = BLACK;
    274. return make_pair(iterator(newnode), true);
    275. }
    276. void RotateL(Node* parent)
    277. {
    278. Node* subR = parent->_right;
    279. Node* subRL = subR->_left;
    280. parent->_right = subRL;
    281. if (subRL)
    282. subRL->_parent = parent;
    283. Node* ppNode = parent->_parent;
    284. subR->_left = parent;
    285. parent->_parent = subR;
    286. if (parent == _root)
    287. {
    288. _root = subR;
    289. _root->_parent = nullptr;
    290. }
    291. else
    292. {
    293. if (parent == ppNode->_left)
    294. {
    295. ppNode->_left = subR;
    296. }
    297. else
    298. {
    299. ppNode->_right = subR;
    300. }
    301. subR->_parent = ppNode;
    302. }
    303. }
    304. void RotateR(Node* parent)
    305. {
    306. Node* subL = parent->_left;
    307. Node* subLR = subL->_right;
    308. parent->_left = subLR;
    309. if (subLR)
    310. subLR->_parent = parent;
    311. Node* ppNode = parent->_parent;
    312. subL->_right = parent;
    313. parent->_parent = subL;
    314. if (parent == _root)
    315. {
    316. _root = subL;
    317. _root->_parent = nullptr;
    318. }
    319. else
    320. {
    321. if (ppNode->_left == parent)
    322. {
    323. ppNode->_left = subL;
    324. }
    325. else
    326. {
    327. ppNode->_right = subL;
    328. }
    329. subL->_parent = ppNode;
    330. }
    331. }
    332. iterator Find(const K& key)
    333. {
    334. Node* cur = _root;
    335. KeyOfT kot;
    336. while (cur)
    337. {
    338. if (kot(cur->_data) < key)
    339. {
    340. cur = cur->_right;
    341. }
    342. else if (kot(cur->_data) > key)
    343. {
    344. cur = cur->_left;
    345. }
    346. else
    347. {
    348. return iterator(cur);
    349. }
    350. }
    351. return End();
    352. }
    353. private:
    354. Node* _root = nullptr;
    355. };

    二. 封装set

    set的底层结构就是红黑树,因此在set中直接封装一棵红黑树,然后将其接口包装下即可

    由于在RBTree中传了KeyOfT来获取K,因此我们在set中需要实现一个仿函数来获取set的K

    1. template<class K>
    2. class set
    3. {
    4. //给红黑树获取K
    5. struct SetkeyOfT
    6. {
    7. const K& operator()(const K& key)
    8. {
    9. return key;
    10. }
    11. };

    其他都是包装RBTree的接口即可

    注意:

    由于set的Key是不能改变的,所以set的iterator应该用const_iterator包装。

    但是会进一步导致insert函数在返回时,由于RBTree的iterator里的参数没有被const修饰是普通迭代器,但是set的iterator是const_iterator,就会出现iterator向const_iterator的转化,这是两个封装后毫无关系的类型,无法直接转化,因此我们需要先提取出来返回值稍作修改后重新封装,因此insert应该做出如下改造:

    1. pairbool> insert(const K& key)
    2. {
    3. //pair::iterator, bool> ret = _t.Insert(key);
    4. auto ret = _t.Insert(key);
    5. return pairbool>(iterator(ret.first._node), ret.second);
    6. }

    注意:

    这里和list实现迭代器一样,当我们typedef迭代器时,会出现内嵌类型的问题,需要使用到typename关键字

    set具体封装的实现代码:

    1. #include "RBTree.h"
    2. namespace mystl
    3. {
    4. template<class K>
    5. class set
    6. {
    7. //给红黑树获取K
    8. struct SetkeyOfT
    9. {
    10. const K& operator()(const K& key)
    11. {
    12. return key;
    13. }
    14. };
    15. public:
    16. typedef typename RBTree::const_iterator iterator;
    17. typedef typename RBTree::const_iterator const_iterator;
    18. //set不能修改,只提供const版本
    19. iterator begin() const
    20. {
    21. return _t.Begin();
    22. }
    23. iterator end() const
    24. {
    25. return _t.End();
    26. }
    27. pairbool> insert(const K& key)
    28. {
    29. //pair::iterator, bool> ret = _t.Insert(key);
    30. auto ret = _t.Insert(key);
    31. return pairbool>(iterator(ret.first._node), ret.second);
    32. }
    33. iterator find(const K& key)
    34. {
    35. return _t.find(key);
    36. }
    37. private:
    38. RBTree _t;
    39. };
    40. }

    三. 封装map

    这里需要的注意事项和set,唯一不同的是这里insert没有set的问题,因为map的iterator就是RBTree的普通迭代器封装的,因map的V是可以更改的,map和set的K是不能更改的,所以map的普通迭代器应该封装成普通的迭代器供V改变,因此,insert可以直接返回封装的insert的返回值。

    map实现了operator[],这里也可以实现,直接封装RBTree的insert,返回值是RBTree返回值的V的引用供修改即可

    实现代码如下:

    1. V& operator[](const K& key)
    2. {
    3. pairbool> ret = insert(make_pair(key, V()));
    4. return ret.first->second;
    5. }

    其他直接封装RBTree的接口即可,j具体实现代码如下:
     

    1. #include "RBTree.h"
    2. namespace mystl
    3. {
    4. template<class K, class V>
    5. class map
    6. {
    7. //给红黑树获取K
    8. struct MapkeyOfT
    9. {
    10. const K& operator()(const pair& kv)
    11. {
    12. return kv.first;
    13. }
    14. };
    15. public:
    16. typedef typename RBTree, MapkeyOfT>::iterator iterator;
    17. typedef typename RBTree, MapkeyOfT>::const_iterator const_iterator;
    18. //map可以修改都提供
    19. iterator begin()
    20. {
    21. return _t.Begin();
    22. }
    23. iterator end()
    24. {
    25. return _t.End();
    26. }
    27. pairbool> insert(const pair& kv)
    28. {
    29. return _t.Insert(kv);
    30. }
    31. iterator find(const K& key)
    32. {
    33. return _t.find(key);
    34. }
    35. V& operator[](const K& key)
    36. {
    37. pairbool> ret = insert(make_pair(key, V()));
    38. return ret.first->second;
    39. }
    40. private:
    41. RBTree, MapkeyOfT> _t;
    42. };
    43. }
  • 相关阅读:
    概念解析 | 网络安全数字孪生(Digital Twin of Cyber Security, DTCS)技术
    【面试经典150 | 矩阵】生命游戏
    无人机实践:DJI A3 飞控---使用
    神经网络和深度学习-梯度下降Gradient Descent
    【智能家居项目】裸机版本——设备子系统(LED && Display && 风扇)
    找不到msvcr120.dll无法执行代码?教你6种方法快速解决问题
    基于Springboot外卖系统11:菜品新增类别+类别信息分页查询
    数据分析的流程是啥样?
    软件测试面试题库和答案解析
    图论第6天
  • 原文地址:https://blog.csdn.net/Britney_dark/article/details/127944455