您的位置:首页 > 其它

map/multimap/set/multiset

2017-05-30 11:38 316 查看
根据数据在容器中的排列特性,分为序列式(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 _Key, class s_Compare, class _Alloc>
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 _Key, class _Tp, class _Compare, class _Alloc>
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 map set