目录
[1.4 哈希函数 (尽量减少冲突次数)](#1.4 哈希函数 (尽量减少冲突次数))
[1.4.1 除法散列法/除留余数法](#1.4.1 除法散列法/除留余数法)
[1.4.2 开放定址法](#1.4.2 开放定址法)
[1.7 链地址法 (解决冲突问题)](#1.7 链地址法 (解决冲突问题))
[二. unordered_map 和 unordered_set](#二. unordered_map 和 unordered_set)
一.哈希
哈希(hash)又称散列,是一种组织数据的方式。从译名来看,有散乱排列的意思。本质就是通过哈希函数把关键字Key跟存储位置建立一个映射关系,查找时通过这个哈希函数计算出Key存储的位置,进行快速查找。
1.1负载因子
假设哈希表中已经映射存储了N个值,哈希表的大小为M,那么负载因子=N/M,负载因子有些地方也翻译为载荷因子/装载因子等,他的英文为load factor。负载因子越大,哈希冲突的概率越高,空间利用率越高;负载因子越小,哈希冲突的概率越低,空间利用率越低;
1.2将关键字转为整数
我们将关键字映射到数组中位置,一般是整数好做映射计算,如果不是整数,我们要想办法转换成整数。哈希表必须要把key转化为整数。
1.3哈希冲突
两个不同的key可能会映射到同一个位置去,这种问题我们叫做哈希冲突,或者哈希碰撞。理想情况是找出一个好的哈希函数避免冲突,但是实际场景中,冲突是不可避免的,所以我们尽可能设计出优秀的哈希函数,减少冲突的次数,同时也要去设计出解决冲突的方案。
比如:

1.4 哈希函数 (尽量减少冲突次数)
1.4.1 除法散列法/除留余数法
除法散列法也叫做除留余数法,顾名思义,假设哈希表的大小为M,那么通过key除以M的余数作为映射位置的下标,也就是哈希函数为:h(key)=key%M。
1.4.2 开放定址法
在开放定址法中所有的元素都放到哈希表里,当一个关键字key用哈希函数计算出的位置冲突了,则按照某种规则找到一个没有存储数据的位置进行存储,开放定址法中负载因子一定是小于的。这里的规则有三种:线性探测、二次探测、双重探测。
**(1)线性探测:**从发生冲突的位置开始,依次线性向后探测,直到寻找到下一个没有存储数据的位置为止,如果走到哈希表尾,则回绕到哈希表头的位置。**h(key)=hash0=key%M,hasho位置冲突了,则线性探测公式为:****hc(key,i)=hashi=(hash0+i) %M, i = {1,2,3,., M- 1},**因为负载因子小于1,则最多探测M-1次,一定能找到一个存储key的位置。

(2)二次探测
从发生冲突的位置开始,依次左右按二次方跳跃式探测,直到寻找到下一个没有存储数据的位置为止,如果往右走到哈希表尾,则回绕到哈希表头的位置;如果往左走到哈希表头,则回绕到哈希表尾的位置;
h(key) = hash0 = key%M,hash0 位置冲突了,则二次探测公式为:
h(key,i) = hashi = (hash0 ± i*i) % M,i = {1,2,3....,M/2}
比如:
(3)双重散列(了解)
第一个哈希函数计算出的值发生冲突,使用第二个哈希函数计算出一个跟key相关的偏移量值,不
断往后探测,直到寻找到下一个没有存储数据的位置为止。
h(key)= hash0 = key%M ,hash0 位置冲突了,则双重探测公式为:
hc(key,i) = hashi = (hash0 + i * h(key))% M, i = {1, 2,3,., M}
1.5让key变为整数
当key是string 等类型时,key不能取模,那么我们需要给其增加一个仿函数,这个仿函数支持把key转换成一个可以取模的整形,如果key可以转换为整形并且不容易冲突,那么这个仿函数就用默认参数即可,如果这个Key不能转换为整形,我们就需要自己实现一个仿函数传给这个参数。
比如:

1.7 链地址法 (解决冲突问题)
哈希表中存储指针,没有数据映射这个位置时,这个指针为空 ,有多个数据映射到这个位置时,我们把这些冲突的数据链接成一个链表,挂在哈希表这个位置下面,链地址法也叫做拉链法或者哈希桶。

二. unordered_map 和 unordered_set
1. unordered_set就不说了,直接说unordered_map,unordered_set的一般应用地址:unordered_map - C++ Reference 需要自己查看
2. unordered_map 和 map差不多可以自行查找资料:unordered_map - C++ Reference
3.主要说明unordered_map 的 operator[] 就行

简要说明就是没有的就会插入,有的就返回其引用。
插入操作,比如:

**返回引用可以对其进行一系列操作(可以解决一些计数的问题),**比如:
