STL中map,multimap,set,multiset,unordered_map,unordered_multimap,unordered_set,unordered_multiset的实现方

来源:互联网 发布:手机号码拦截软件 编辑:程序博客网 时间:2024/06/05 15:07

转自:http://blog.csdn.net/duyiwuer2009/article/details/23780041


1. map, multimap, set, multiset

g++ 中 map, multimap, set, multiset 由红黑树实现

map: bits/stl_map.h

multimap: bits/stl_multimap.h

set: bits/stl_set.h

multiset: bits/stl_multiset.h

红黑树类——_Rb_tree: bits/stl_tree.h

若要分析红黑树的实现阅读 bits/stl_tree.h 即可


2. std::pair

位于 <utility>, 本质非常简单,就是一个含有 2 个成员的类模板:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. // bits/stl_pair.h  
  2. template<class _T1, class _T2>  
  3. struct pair  
  4. {  
  5.     typedef _T1 first_type;    /// @c first_type is the first bound type  
  6.     typedef _T2 second_type;   /// @c second_type is the second bound type  
  7.   
  8.     _T1 first;                 /// @c first is a copy of the first object  
  9.     _T2 second;                /// @c second is a copy of the second object  
  10. ......  
  11. };  

与之相关的比较重要的函数:

2.1 make_pair()

见例子

2.2 重载关系操作符

比较规则就是前面博文介绍的字典序比较(http://blog.csdn.net/duyiwuer2009/article/details/23277803),和 deque, list 等也类似,map 的比较是基于它的(因为 map 是存储着元素为 pair<key, value> 的容器,下文详细说明)。


3. map, set 的相似和本质

先看 gcc libstdc++ 实现代码:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. // bits/stl_tree.h  
  2. template<typename _Key, typename _Val, typename _KeyOfValue,  
  3.         typename _Compare, typename _Alloc = allocator<_Val> >  
  4. class _Rb_tree  
  5. {  
  6. ......  
  7. public:  
  8.     typedef _Key key_type;  
  9.     typedef _Val value_type;  
  10. ......  
  11. };  
  12.   
  13.   
  14. // bits/stl_map.h  
  15. template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,  
  16.         typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >  
  17. class map  
  18. {  
  19. public:  
  20.     typedef _Key                         key_type;  
  21.     typedef _Tp                          mapped_type;  
  22.     typedef std::pair<const _Key, _Tp>   value_type;  
  23.     typedef _Compare                     key_compare;  
  24. ......  
  25.   
  26. public:  
  27.     class value_compare  
  28.     : public std::binary_function<value_type, value_type, bool>  
  29.     {  
  30.         friend class map<_Key, _Tp, _Compare, _Alloc>;  
  31.     protected:  
  32.         _Compare comp;  
  33.   
  34.         value_compare(_Compare __c)  
  35.         : comp(__c) { }  
  36.   
  37.     public:  
  38.         bool operator()(const value_type& __x, const value_type& __y) const  
  39.         { return comp(__x.first, __y.first); }  
  40.     };  
  41. ......  
  42.     typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,  
  43.                 key_compare, _Pair_alloc_type> _Rep_type;  
  44.   
  45.     /// The actual tree structure.  
  46.     _Rep_type _M_t;  
  47. ......  
  48. };  
  49.   
  50.   
  51. // bits/stl_set.h  
  52. template<typename _Key, typename _Compare = std::less<_Key>,  
  53.         typename _Alloc = std::allocator<_Key> >  
  54. class set  
  55. {  
  56. ......  
  57.     typedef _Key     key_type;  
  58.     typedef _Key     value_type;  
  59.     typedef _Compare key_compare;  
  60.     typedef _Compare value_compare;  
  61. ......  
  62.     typedef _Rb_tree<key_type, value_type, _Identity<value_type>,  
  63.                     key_compare, _Key_alloc_type> _Rep_type;  
  64.     _Rep_type _M_t;  // Red-black tree representing set.  
  65. ......  
  66. };  

可以看出:

1. map 的 value_type 为 std::pair<const _Key, _Tp>, 而 set 的 value_type 为 _Key, 都是通过 _Key 进行定位。

2. 从容器中存储元素的角度而言,关联容器与序列容器是一样的,只不过 map 存储的是 std::pair<const _Key, _Tp> (从 begin(), end() 返回的迭代器类型上也可以看出),区别是有个 key 与之关联。

3. 从用途上来说,set 相当于集合,方便剔除和增加新元素,map 自不用多说。


附:常见容器分类

序列容器(sequence container):

vector

list

deque

容器适配器(container adapter):

stack(last in, first out)

queue(first in, first out)

priority_queue

关联容器(associative container):

set

multiset

map

multimap


4. 红黑树

红黑树(red–black tree)是一种自平衡二叉查找树(self-balancing binary search tree),先看二叉查找树(BST)的定义和性质:

(1) 若它的左子树非空,则左子树上所有节点的值均小于它的根节点的值;

(2) 若它的右子树非空,则右子树上所有节点的值均大于(或大于等于)它的根节点的值;

(3) 它的左、右子树也分别为二叉查找树。(显然这是一个递归定义)


(4) 中序遍历(LDR: left subtree, current node(data), right subtree)将得到递增序列,所以又叫二叉排序树


5. unordered_map, unordered_multimap, unordered_set, unordered_multiset(C++ 11)

g++ 中 unordered_map, unordered_multimap, unordered_set, unordered_multiset 由哈希表实现

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. unordered_map       <-- __unordered_map      \  
  2. unordered_multimap  <-- __unordered_multimap -\  
  3.                                                | <-- std::_Hashtable(hashtable.h)  
  4. unordered_set       <-- __unordered_set      -/  
  5. unordered_multiset  <-- __unordered_multiset /  

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. std::_Hashtable(hashtable.h) <-- std::__detail::_Rehash_base(hashtable_policy.h)  
0 0
原创粉丝点击