无序容器是 C++ 11 标准才正式引入到 STL 标准库中的,如果要使用该类容器则必须选择支持 C++ 11 标准的编译器。和关联式容器一样无序容器也使用键值对(pair 类型)的方式存储数据。不过,它们有本质上的不同:
关联式容器的底层实现采用的树存储结构,更确切的说是红黑树结构;
无序容器的底层实现采用的是哈希表的存储结构。
因此和关联式容器相比,无序容器具有以下 2 个特点:
无序容器内部存储的键值对是无序的,各键值对的存储位置取决于该键值对中的键
和关联式容器相比,无序容器擅长通过指定键查找对应的值(平均时间复杂度为 O(1))但对于使用迭代器遍历容器中存储的元素,无序容器的执行效率则不如关联式容器。
无需容器底层实现原理
一、unordered_map
(1)基本应用及原理 (声明 建立 插入 查找 迭代器访问举例)
unordered_map 容器,就是"无序 map 容器",它不会像 map 容器那样对存储的数据进行排序。底层采用的是哈希表存储结构,该结构本身不具有对数据的排序功能,所以此容器内部不会自行对存储的键值对进行排序
换句话说,unordered_map 容器和 map 容器仅有一点不同,即 map 容器中存储的数据是有序的,而 unordered_map 容器中是无序的。
头文件/<unordered_map>
template < class Key, //键值对中键的类型
class T, //键值对中值的类型
class Hash = hash<Key>, //容器内部存储键值对所用的哈希函数
class Pred = equal_to<Key>, //判断各个键值对键相同的规则
class Alloc = allocator< pair<const Key,T> > // 指定分配器对象的类型
> class unordered_map;
以上 5 个参数中,必须显式给前 2 个参数传值,并且除特殊情况外,最多只需要使用前 4 个参数
默认哈希函数只适用于基本数据类型(包括 string 类型),而不适用于自定义的结构体或者类。
当无序容器中存储键值对的键为自定义类型时,默认的哈希函数 hash 以及比较函数 equal_to 将不再适用
只能自己设计适用该类型的哈希函数和比较函数,并显式传递给 Hash 参数和 Pred 参数。
(2) 元素访问的三种方法(迭代器 / 键 / at)
//求两个链表的相交节点
ListNode *p=headA,*q=headB,*res=NULL;
unordered_map<ListNode*,int> Hash; //声明 键值对<key,value>
for(int i=0;p;p=p->next,i++){
Hash.insert<make_pair(p,i)>; //三种插入方式都可以
Hash.insert({
p,i})