哈希表以及封装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[] 就行

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

插入操作,比如:

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

相关推荐
Jiber King20 分钟前
语法基础课1.1 变量、输入输出、表达式和顺序语句
数据结构·c++·算法
珹洺1 小时前
C++从入门到实战(六)类和对象(第二部分)C++成员对象及其实例化,对象大小与this详解
java·开发语言·汇编·数据结构·c++·sql·算法
小林熬夜学编程1 小时前
【高并发内存池】第三弹---构建Central Cache的全方位指南——从整体设计到核心实现
c语言·开发语言·数据结构·c++·算法
Run_Teenage2 小时前
C语言 数据结构【动态顺序表】详解
c语言·开发语言·数据结构
鸭梨大大大3 小时前
LinkedList与链表
java·数据结构·链表
LCY13311 小时前
数据库与其所用数据结构
数据结构·数据库
Dust-Chasing13 小时前
数据结构之顺序表和栈
c语言·数据结构·算法
沉默的煎蛋15 小时前
深入理解 TCP 三次握手与四次挥手
java·网络·数据结构·网络协议·tcp/ip
JKHaaa15 小时前
判断是不是完全二叉树(C++)
数据结构·c++·算法
阑梦清川16 小时前
蓝桥杯关于栈这个数据结构的一个算法题目
数据结构·算法·蓝桥杯