本部分内容包括set,multiset,map,multimap。
一、set和multiset
set的insert()使用的是红黑树的insert_unique(),multiset的insert()使用的是红黑树的insert_qual(),下面是G2.9的set源码:
template <class Key,
class Compare = less<Key>,
class Alloc = alloc>
class set{
public:
typedef Key key_type;
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
private:
typedef rb_tree<key_type, value_type,
identity<value_type>, key_compare, Alloc> rep_type;
rep_type t;
public:
typedef typename rep_type::const_iterator iterator;
......
};
注意set和multiset都不能用iterator改变元素的值,因为这会破坏红黑树的结构,所以它们的iterator使用的是红黑树的const_iterator
二、map和multimap
1. 概述
注意multimap的multi的含义是key可以重复,有时候即使key重复,只要data不一样,multimap中存的东西还是不一样的。
template <class Key,
class T,
class Compare = less<Key>,
class Alloc = alloc>
class map{
public:
typedef Key key_type;
typedef T data_type;
typedef T mapped_type;
typedef pair<const Key, T> value_type;
typedef Compare key_compare;
private:
typedef rb_tree<key_type, value_type,
select1st<value_type>, key_compare, Alloc> rep_type;
rep_type t;
public:
typedef typename rep_type::iterator iterator;
......
};
template<class Pair>
struct select1st:
public unary_function<Pair, typename Pair::first_type>{
const typename Pair::first_type&
operator()(const Pair& x) const
{ return x.first; }
};
template<class Arg, class Result>
struct unary_function{
typedef Arg argument_type;
typedef Result result_type;
};
map和multimap也不能通过迭代器改变key的值,这是通过将pair的第一个参数设置为const实现的,map和multimap的迭代器就是红黑树的普通迭代器。
2. map使用operator[]进行插入操作的原理
Returns data associated with the key specified in subscript. If the key does not exist, a pair with that key is created using default values, which is then returned.
mapped_type&
operator[](const key_type& __k)
{
iterator __i = lower_bound(__k); //返回第一个不小于__k的元素的位置
if(__i == end() || key_compare()(__k, (*__i).first))
__i = insert(__i, value_type(__k, mapped_type()));
return (*__i).second;
}
注意返回的是引用,所以可以用类似mp[i] = val的方式插入元素。