map/set/multi_map/multi_sep底层实现是加头节点的红黑树,元素之间有序,当存放的是自定义类型的时候要重载operator<,中序遍历的时候是有序的。增删查的时间复杂度都是O(lgN)
map存放的是键值对<key,value>,,key唯一,value可以重复,不能修改key的值,可以先删除旧的值,再添加新的值,value的值可以修改。
set用户存放的是值,但是底层存放的仍能存放的是键值对,只不过key=value,同样的值是唯一的,不能随便修改value.
mulit_map/multi_set与map/set相比,大部分都是相同的,只是存放的元素可以不唯一,可以重复。
set/multiset不区分键值和实值,其键值就是实值,会根据待定的排序准则,自动将元素排序。两者唯一的不同在于前者不允许元素重复(底层调rb_tree::insert_unique()),而后者允许(底层调用rb_tree::insert_equal())。
和set相比,map/multimap同时拥有实值(value)和键值(key),其每一个元素都是pair<key,value>
,pair的第一个元素是键值,第二个元素是实值。map和multimap的唯一区别在于,map不允许两个元素拥有相同的键值(底层调rb_tree::insert_unique()),而multimap允许存在重复的键值(底层调用rb_tree::insert_equal())。
unordered_map/unordered_set底层实现用了哈希表,
(1)unordered_set存放的是value,unorder_map也是存储的key-value的值,可以通过key快速索引到value,但是不会根据key的大小进行排序,增删查的时间复杂度都是O(1)
(2)同样不能修改key值当存放的是自定义的元素类型的时候,需要定义hash_value函数并且重载operator==,重载operator==是因为,如果两个元素的通过哈希函数计算出的值相同,并不能断定这两个元素就相同,必须再调用operator==。
(3)散列值相同的被存储在一个桶里。当散列容器中有大量数据时,同一个桶里的数据也会增多,造成访问冲突,降低性能。为了提高散列容器的性能,unordered库会在插入元素是自动增加桶的数量,不需要用户指定。但是,用户也可以在构造函数或者rehash()函数中,指定最小的桶的数量
unordered_map/unordered_set 与map/set结论:
运行效率方面:unordered_map/unordered_set 最高,而map/set效率较低但 提供了稳定效率和有序的序列。
占用内存方面:map/set内存占用略低,unordered_map/unordered_set内存占用略高,而且是线性成比例的。