map/multimap/set/multiset

根据数据在容器中的排列特性,分为序列式(sequeence)和关联式(associative)
  • 序列式容器:其中元素可序,但不一定有序,容器通过元素在容器中的位置顺序存储和访问元素

    • C++本身提供了一个序列式容器:数组(array);
    • STL中提供了vector,list,slist,deque,stack,queue,heap,priority-queue
    • 其中stack和queue只是对deque进行了封装,所以被称为适配器
  • 关联式容器:每个元素都有一个键值(key)和一个实值(value),通过键值存储和查找元素;

    • 标准的关联式容器有set(集合)和map(映射表);以及根据set和map衍生出来的multiset和multimap;这些容器底层都是RB-Tree(红黑树)
    • 另外STL还提供了非标准的hash table(散列表),以及以hash table 为底层机制实现的hash_set(散列集合),hash_map(散列映射表),hash_multiset(散列多键集合),hash_multimap(散列多键映射表)

set特性
  • 所有元素都会根据元素的键值自动排序,默认为升序
  • set元素的键值就是实值,实值就是键值,所以不能通过迭代器改变元素的值
...
template 
class set {
//模板参数可以看出只有一个键值
...
typedef typename _Rep_type::const_iterator iterator;
//从源码中可以看到set的迭代器被定义为RB-Tree的const_iterator
//是一种constant iterator(mutable iterator)
  • set不允许两个元素有相同的键值,所以插入元素调用的是底层机制RB-Tree的insert_unique()

multiset和set的唯一差别在于它允许键值重复,因此它的插入操作采用底层机制RB-Tree的insert_equal()
//部分源码
//从源码中可以看到调用的是insert_equal()
  template <class _InputIterator>
  multiset(_InputIterator __first, _InputIterator __last)
    : _M_t(_Compare(), allocator_type())
    { _M_t.insert_equal(__first, __last); }//****

  template <class _InputIterator>
  multiset(_InputIterator __first, _InputIterator __last,
           const _Compare& __comp,
           const allocator_type& __a = allocator_type())
    : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }//****

#else

  multiset(const value_type* __first, const value_type* __last)
    : _M_t(_Compare(), allocator_type())
    { _M_t.insert_equal(__first, __last); }

  multiset(const value_type* __first, const value_type* __last,
           const _Compare& __comp,
           const allocator_type& __a = allocator_type())
    : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }

  multiset(const_iterator __first, const_iterator __last)
    : _M_t(_Compare(), allocator_type())
    { _M_t.insert_equal(__first, __last); }

  multiset(const_iterator __first, const_iterator __last,
           const _Compare& __comp,
           const allocator_type& __a = allocator_type())
    : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }

map特性
  • 所有元素都会根据元素的键值自动排序,默认为升序
  • map的所有元素都是pair,同时拥有键值(key)和实值(value)

    • pair模板类用来绑定两个对象为一个新的对象,该类型在头文件中定义

      template<class T1,class T2>
      struct pair
      {
          typedef T1 first_type;
          typedef T2 second_type;
          T1 first;
          T2 second;
          pair()
          :first(T1()),second(T2()){}
          pair(const T1&a,const T2& b)
          :first(a),second(b){}
      };
...
template 
class map {
//从模板参数可以看出键值和实值都存在
...
  • map不允许有相同的键值,所以插入元素调用的是底层机制RB-Tree的insert_unique()
  • map的键值不允许修改,实值可以修改

multimap和map的唯一差别在于它允许键值重复,所以调用的是底层机制RB-Tree的insert_equal()
//与map不同的地方
 template <class _InputIterator>
  multimap(_InputIterator __first, _InputIterator __last)
    : _M_t(_Compare(), allocator_type())
    { _M_t.insert_equal(__first, __last); }

  template <class _InputIterator>
  multimap(_InputIterator __first, _InputIterator __last,
           const _Compare& __comp,
           const allocator_type& __a = allocator_type())
    : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }
#else
  multimap(const value_type* __first, const value_type* __last)
    : _M_t(_Compare(), allocator_type())
    { _M_t.insert_equal(__first, __last); }
  multimap(const value_type* __first, const value_type* __last,
           const _Compare& __comp,
           const allocator_type& __a = allocator_type())
    : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }

  multimap(const_iterator __first, const_iterator __last)
    : _M_t(_Compare(), allocator_type())
    { _M_t.insert_equal(__first, __last); }
  multimap(const_iterator __first, const_iterator __last,
           const _Compare& __comp,
           const allocator_type& __a = allocator_type())
    : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }

map的元素是“键-值”对的二元组形式:键用作元素在map中的索引,而值则表示所存储和读取的数据。set仅包含一个键,并有效地支持关于某个键是否存在的查询。set和map类型的对象所包含的元素都具有不同的键。如果需要一个键对应多个实例,则需要使用multimap或multiset类型。这两种类型允许多个元素拥有相同的键。

你可能感兴趣的:(stl)