c++set/multiset/map/multimap/ vs unordered_set/unordered_multiset/uordered_map/unordered_multimap

set:有序集合,元素不可重复,底层实现默认为红黑树,即一种特殊的二叉查找树(BST)。它可以在 O(n log n) 的时间排序数组,O(log n) 的时间插入、删除、查找任意值,O(log n) 的时间获得最小或最大值。这里注意,set 和 priority_queue 都可以用于维护数据结构并快速获取最大最小值,但是它们的时间复杂度和功能略有区别,如priority_queue 默认不支持删除任意值,而 set 获得最大或最小值的时间复杂度略高,具体使用哪个根据需求而定。

multiset:支持重复元素的 set。

map:有序映射或有序表,在 set 的基础上加上映射关系,可以对每个元素 key 存一个值 value。
multimap:支持重复元素的 map。

unordered_set:哈希集合,可以在 O(1) 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。
unordered_multiset:支持重复元素的 unordered_set。
unordered_map:哈希映射或哈希表,在 unordered_set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 vector 代替 unordered_map,用位置表示 key,用每个位置的值表示 value。
unordered_multimap:支持重复元素的 unordered_map。

有序版和无序版的区别主要在于底层实现,有序版默认红黑树,无序版默认哈希表
红黑树:Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。红黑树的应用比较广泛,主要是用它来存储有序的数据,它的时间复杂度是O(lgn)(二叉树最大查找次数等于树的深度)。例如,Java集合中的TreeSet和TreeMap,C++ STL中的set、map,以及Linux虚拟内存的管理,都是通过红黑树去实现的。

红黑树的特性:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶节点是黑色。 [注意:这里叶节点,是指为空(NIL或NULL)的叶子节点!]
(4)如果一个节点是红色的,则它的子节点必须是黑色的,红色节点的孩子和父亲都不能是红色。
(5)任意一结点到每个叶子结点的路径都包含数量相同的黑结点。
关键是红黑树的自平衡调整。当新加入或删除数据不满足红黑树特性后会左旋右旋变色调整使重新满足红黑树的特性。

哈希表(Hash table,也叫散列表),是根据键值(Key)而直接进行访问的数据结构。也就是说,它通过把键值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key),adr = f(key)。查找时,根据这个确定的对应关系找到给定值key的映射f(key),若查找集合中存在这个记录,则必定在f(key)的位置上。我们把这种对应关系f称为散列函数,又称为哈希函数(Hash).按这个思想,采用散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间称为散列表或哈希表(Hash table)。关键字对应的记录存储位置称为散列地址。

ref: https://blog.csdn.net/qq_30815237/article/details/91049223