关联容器——学习笔记

关联式容器总结图示

六种关联式容器

插入元素只有 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]); 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值