C++ STL中set和map底层数据结构为红黑树rb_tree。具体可以参考这篇文章。       

C++ STL :红黑树rb_tree源码剖析

set插入时插的就是key, map插入时插的是value(键值对), 排序时底层的红黑树会根据key_compare(也就是模版参数中的Compare)来比较key的大小。

set/multiset的实现调用rb_tree的接口实现。

template <class Key, class Compare = less<Key>, class Alloc = alloc>
class set {
public:
    typedef Key key_type;
    typedef Key value_type;  // 使用的value类型跟key一样
    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:
    // 接口的实现只是对rb_tree的封装  不一一列举了
    iterator begin() const { return t.begin(); }
    iterator end() const { return t.end(); }
    pair<iterator,bool> insert(const value_type& x) {
        pair<typename rep_type::iterator, bool> p = t.insert_unique(x);
        return pair<iterator, bool>(p.first, p.second);
    }
    // ...
};

set类中定义一个rb_tree,然后set中的操作都是使用rb_tree来实现。

其中set跟multiset不一样的是,set插入的时候调用的是insert_unique(),而multiset调用的是insert_equal()。


map/mulitmap的实现也是通过调用rb_tree的接口。

map/mulitmap区别:map插入的时候调用的是insert_unique(),而multimap调用的是insert_equal()。

下面是map的实现

template <class Key, class T, class Compare = less<Key>, class Alloc
class map {
public:
    typedef Key key_type;
    typedef T data_type;
    typedef T mapped_type;
    typedef pair<const Key, T> value_type; // 在rb_tree中value的类型是pair
    typedef Compare key_compare;
private:
    // select1st直接return T.first 用于rb_tree取到key进行比较大小
    typedef rb_tree<key_type, value_type,
                  select1st<value_type>, key_compare, Alloc> rep_type;
    rep_type t;
    // ...

    // 接口只是对rb_tree的封装  就不一一列举了
    iterator begin() { return t.begin(); }
    iterator end() { return t.end(); }
    pair<iterator,bool> insert(const value_type& x) { return t.insert_unique(x); }
     // ...
}

map和set容器中key不能修改是怎么实现的。

C++ STL:set/multiset、map/multimap源码剖析_c++

   set的iterator定义为rep_type::const_iterator,这样获取的set的迭代器默认就是常量迭代器,自然就不能去修改set中的key值。 

 对于一个map容器,每次插入、删除或者查找返回的迭代器,其指向的红黑树中node节点,对其使用迭代器,解出的值的类型是value_type,这是一个pair的包装类,红黑树中定义了它的Key为const Key,而其值的类型为T,这样对于每次返回的迭代器就可以实现,其中Key为const类型不能修改,对于实值不是const,可以修改。