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

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

插入操作,比如:

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

相关推荐
张张努力变强1 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
wWYy.1 小时前
数组快排 链表归并
数据结构·链表
李斯啦果2 小时前
【PTA】L1-019 谁先倒
数据结构·算法
Mr Xu_17 小时前
告别硬编码:前端项目中配置驱动的实战优化指南
前端·javascript·数据结构
czxyvX17 小时前
017-AVL树(C++实现)
开发语言·数据结构·c++
数智工坊18 小时前
【数据结构-队列】3.2 队列的顺序-链式实现-双端队列
数据结构
elseif12318 小时前
【C++】并查集&家谱树
开发语言·数据结构·c++·算法·图论
徐小夕@趣谈前端18 小时前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
不穿格子的程序员19 小时前
从零开始写算法——普通数组篇:缺失的第一个正数
算法·leetcode·哈希算法
Nebula_g19 小时前
线程进阶: 无人机自动防空平台开发教程(更新)
java·开发语言·数据结构·学习·算法·无人机