C++ STL中set和map底层数据结构为红黑树rb_tree。具体可以参考这篇文章。
C++ STL :红黑树rb_tree源码剖析-CSDN博客
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不能修改是怎么实现的。
set的iterator定义为rep_type::const_iterator,这样获取的set的迭代器默认就是常量迭代器,自然就不能去修改set中的key值。
对于一个map容器,每次插入、删除或者查找返回的迭代器,其指向的红黑树中node节点,对其使用迭代器,解出的值的类型是value_type,这是一个pair的包装类,红黑树中定义了它的Key为const Key,而其值的类型为T,这样对于每次返回的迭代器就可以实现,其中Key为const类型不能修改,对于实值不是const,可以修改。
参考:
https://www.cnblogs.com/runnyu/p/6004837.html