关联式容器总结图示
六种关联式容器
插入元素只有 insert 的做法,map可以用 [ ] 操作符
总结一:六种容器
在C++语言中,set 分别提供了三种数据结构:
set
multiset
unordered_set在C++语言中,map 分别提供了三种数据结构:
map
multimap
unordered_map
总结二:底层实现
底层实现为哈希表:unordered_set、unordered_map
底层实现为红黑树:set,multiset,map,multimap 注意:只能删除和增加红黑树是一种平衡二叉搜索树,所以key值是有序的,但key不可以修改,改动key值会导致整棵树的错乱,所以只能删除和增加。
总结三:使用规律
当我们要使用集合来解决哈希问题的时候,
1、优先使用unordered_set,因为它的查询和增删效率是最优的,
2、如果需要集合是有序且没有重复的,那么就用set,
3、如果要求不仅有序还要有重复数据的话,那么就用multiset。虽然set、multiset 的底层实现是红黑树,不是哈希表,但是set、multiset 依然使用哈希函数来做映射,只不过底层的符号表使用了红黑树来存储数据,所以使用这些数据结构来解决映射问题的方法,我们依然称之为哈希法。map也是一样的道理。
总结四:数组&哈希
数组可以当做哈希表来用: 但是当哈希值比较少,特别分散,跨度非常大时,使用数组就造成空间的极大浪费
总结五:有序&无序
对哈希表的无序的理解:
1、什么是无序,什么是有序?
所谓有序和无序,是是否按关键字的输入顺序保存元素。
无序指的是不按你给的信息去排序,哈希表有一个哈希函数,通过哈希函数可以把 key 转为 index ,所以哈希表的底层其实是一个 array + list 链表。array 的 index 就是 key 经过哈希之后转换成的,然后再把 key 和 value 放进链表里。因此称之为无序。
无序的是unordered_map、 unordered_set。 采用迭代器遍历出来的元素是无序的, 这是因此底层实现数据结构为哈希表。
有序是指:使用迭代器遍历的时候,按照输入的顺序
比如:
unordered_set set1;
set set2;
在set1和 set2 中都输入 a b c则有:
set1无序: set1[0]=c, set1[1]=b, set1[2]=a
set2有序: set2[0]=a, set2[1]=b, set2[2]=c
懂了木有,这就是无序,因为unordered_set的底层实现是哈希表,它会将你输入的重新排列,并不会按照你输入的顺序来存储,这也就是为什么哈希表查找时间为O(1)
pair 对组
// 插入pair对组时,需要用大括号
queue<pair<TreeNode*, TreeNode*>> que;
que.push({cur->left, cur});
C++ map容器
插入元素
第一种:
pair<iterator,bool>
示例:有三种写法
m.insert(pair<int,string>(1,"I"));
m.insert(make_pair(1,"I"))
m.insert({1,"I"});
第二种:
template <class P> pair<iterator,bool>
示例:m.insert(map<int,string>::value_type(2,"am"));
第三种:
operator[](也就是通过[]来实现插入元素)
注意:操作符[]还可以作为访问某个key值对应的元素
示例:m[3]="happy";
m[key]=value;
首先要明确,map容器中的key值是不可重复的,
第一种是通过pair,第二种是类模板,但这两种本质上没有区别,都是insert实现的;
当map中有这个关键字时,前两种insert操作就无法插入,pair返回值的第二个元素 bool=false;
第三种operator[],当插入时map中有这个关键字,仍会成功插入,且会覆盖掉原先的数据。
operator [ ]
对于m[k]
如果k匹配容器中某个元素的键,函数将返回对其映射值的引用。
如果k与容器中任何元素的键都不匹配,函数就会用该键插入一个新元素,并返回对该元素映射值的引用。
请注意,即使没有给元素分配映射值(元素是使用默认构造函数构造的),这也总是将容器大小增加1。
C++ set 容器
find
// find(k) 找到 used 容器中第一个出现 k 元素对应的迭代器,如果没有找到,则返回 used.end() [也就是尾后迭代器]
// 注意这个返回的是迭代器哦~
unordered_set<int> uset;
if((uset.find(nums[i]) != uset.end())
{
uset.insert(nums[i]);
}