大概的看一下set的源码:
template < class key, key的类型
class compare=less, 比较key的方法
class Alloc=alloc>
class set
{
public:
typedef key key_type;
typedef key value_type; //从这里就可以看出,对于set 数据和key是同一个值
typedef compare key_compare;
typedef compare value_cpmpare;//从后俩行可以看出,比较key就是在比较value的值
private:
typedef rb_tree> rbp_type;
//从这里可以看出,底层数据结构只有一颗红黑树
rbp_type t;
public:
typedef typename rep_type::const_iterator iterator;
//这里指定我们set使用的是rb_tree的const iterator,所以从这里禁止了我们修改key。
//而set的所有操作都是基本都是调用了rb_tree的接口来完成的。
};
总结一下:
1.set的key必须独一无二,multiset的key可以重复
最大区别的原因:
2.由于set在调用insert()时,调用的时红黑树的insert_unique(),即就是要插入独一无二的节点,否则失败;
3.而multiset调用自己的insert()时,调用的红黑树的insert_equal(),即可以插入重复的数据。
4.即便如此他俩都使用红黑树的const_iterator,不允许我们去修改key。(实际上红黑树的肯定是支持我们修改key的,但那时由于每次修改会造成树的不平衡,还需要我们进行平衡操作,实在影响效率,所以在set和multiset中将可修改禁止了)
再看看使用的时候的关系:
set和multiset底层都是调用红黑树的接口,所有我们也可以将set/multiset 看作是容器适配器。