哈希表以及封装unordered_map及其set

目录

一.哈希

1.1负载因子

1.2将关键字转为整数

1.3哈希冲突

[1.4 哈希函数 (尽量减少冲突次数)](#1.4 哈希函数 (尽量减少冲突次数))

[1.4.1 除法散列法/除留余数法](#1.4.1 除法散列法/除留余数法)

[1.4.2 开放定址法](#1.4.2 开放定址法)

1.5让key变为整数

[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\[\] 就行

简要说明就是没有的就会插入,有的就返回其引用。

插入操作,比如:

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

相关推荐
by2099917 小时前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表
Code_Solitude17 小时前
c语言:关于qsoet函数知识点
c语言·数据结构·算法
Nil20818 小时前
leetcode 49字母异位分组
算法·leetcode·哈希算法
Pniubi19 小时前
快速排序(力扣基础)(递归)
java·数据结构·算法
inrichtt1 天前
第八课时:SPI总线揭秘:四线全双工通信的奥
c语言·数据结构·stm32·单片机·嵌入式硬件
HPtiger1 天前
数据结构——选择排序
数据结构·算法·排序算法
DongQiShanRen1 天前
六根硬件映射(四):归属澄清、两处不一致与卷十一总表
开发语言·人工智能·算法·rust·哈希算法·集成学习
丑梨数据1 天前
信创环境里跑文档工具:格式兼容与本地合规的几个坑
数据结构·人工智能·算法·决策树·排序算法
烂蜻蜓1 天前
Pandas入门教程(四):Series数据结构——创建、索引与常用方法
数据结构·pandas
开开心心就好1 天前
多份文档怎么批量打印?支持多种格式
java·服务器·开发语言·pdf·ocr·散列表·启发式算法