哈希表的学习

概念:

哈希又称为散列,一种组织数据的方式;有散乱排列的意思

本质是通过哈希函数把关键字Key跟存储位置建立映射关系,查找时通过这个哈希函数计算出Key的位置以进行快速查找

1. 直接定址法 --- 用关键字计算出一个绝对位置或相对位置

一组0,9之间的关键字,我们开一个10个数的数组,每个关键字的值就是存储位置的下标

a,x的一组小写字母,我们开一个24个数的数组,每个关键字acsii就是存储位置的下标

当关键字的范围比较分散时,内存会被浪费或者内存不够

N个值,M个空间 ,M>=N,关键字key放到数组的k(key)位置,k(key)在[0,M)内

哈希冲突:

两个不同的key可能会映射到同一个位置上

负载因子:

N:哈希表中映射存储的值的个数

M:哈希表的大小

负载因子:N/M

负载因子越大,哈希冲突概率越高,空间利用率越高

关键字转为整数:

我们将关键字映射到数组中的位置,整数更方便做映射计算;不是整数的,我们要转换成整数

哈希函数:

一个好的哈希函数应该是让N个关键字被等概率的均匀地散列分布到哈希表的M个空间中,当然,这是很难做到的,我们尽可能地设计这样的哈希函数去实现

除法散列法/除留余数法

M:哈希表的大小

哈希函数:h(key)=key%M

要尽量避免M为2的幂10的幂

乘法散列法

关键字K乘A(0<A<1),取出K*A的小数部分,再用M*抽取出的小数部分,再向下取值

h(key)=floor(M*((A*key)%1.0)

A最好取值为黄金分割点即为0.6180339887

全域散列法

增加函数的随机性

P:足够大的质数

a:1,P-I内的任意整数

b:0,P-1内的任意整数

处理哈希冲突

开放定址法和链地址法

采用开放定址法处理散列表的冲突时,其平均查找长度高于链接法处理冲突。开放地址法一旦产生冲突,冲突容易连在一起,引起一脸篇的冲突,链地址法一般不会

开放地址法

负载因子是小于1的

所有的元素都放到哈希表中,当有关键字key用哈希函数计算出的位置有冲突,就按规则找一个没有存储数据的位置进行存储

这里有线性探测,二次探测,双重探测

线性探测

从发生冲突的位置开始依次线性向后探测直到寻找到下一个没有存储数据的位置,如果走到哈希表的表尾,就绕回到哈希表的表头位置

hash0位置冲突,则

线性探测会出现堆积现象(踩踏)。堆积现象对求平均查找长度影响比较大

线性探测采用未删除法,当从哈希表中删除某个元素时,并没有将该元素真正的删除掉,而是采用标记的方式处理,但是不能直接将该位置标记为空,否则会影响从该位置产生冲突的元素的查找

例:

M=11

{19,30,5,36,13,20,21,12}

h(19)=19%11=8,所以19存储在下标为8的位置

h(30)=30%11=8,但是下标为8的位置以及存储了19,所以30存储在下标为9的位置

h(5)=5

h(36)=3

h(13)=2

h(20)=9,位置被占了就继续往后占

h(21)=10,也是同样

二次探测

先加一下再减一下

位置发生冲突时,依次左右按二次方跳跃式探测,直到寻找到下一个没有存储数据的位置,如果走到哈希表的表尾,就绕回到哈希表的表头位置

hash0位置冲突,则,当,hashi<0时,hashi += M

例:

{19,30,52,63,11,22}

M=11

h(19)=8

h(30)=8,hc(30,1)=hash1=(8+1*1)%11=9

h(52)=8,hc(52,1)=hash1=(8-1*1)%11=7

h(63)=8,hc(63,2)=hash2=(8+2*2)%11=1

h(11)=0

h(22)=0,hc(22,1)=hash1(0+1)%11=1,有了

所以hc(22,1)=hash1(0-1)%11=-1<0,hash1+= 11 --> 10

例题:

某个哈希表的n个关键字具有相同的哈希值,如果使用二次探测再散列法(属于二次探测,探查序列为 Hi​=(H0​+i2)%m(i=1,2,⋯ ,m 为哈希表长度) )将这n个关键字存入哈希表,至少要进行()次探测

n个关键字具有相同的哈希值,会产生冲突,需要依次寻找下一个可以使用的位置

元素1:探测1次

元素2:探测2次,因为第一个关键字占用了原本冲突的位置

......

所以总共需要探测 1+2+ ... + n = n*(n+1)/2

链地址法/哈希桶/拉链法

所有的数据不再直接存储在哈希表中,哈希表中存储一个指针,没有数据映射这个位置时,这个指针为空,++有多个数据映射到这个位置时,我们把冲突的这些数据链接成一个链表挂在哈希表的位置下面++

例:

{19,30,5,36,13,20,21,12,24,96}

M=11

h(19)=19%11=8

h(30)=30%11=8

h(5)=5

h(36)=3

h(13)=2

h(20)=9

h(21)=10

h(12)=1

h(24)=2

h(96)=88

链地址法的负载因子没有限制可以大于1

负载因子越大,哈希冲突该=概率越高,空间利用率越高

例题:

一个关键字序列:(19,14,23,1,68,20,84,27,55,11,10,79)散列存储在一个哈希表中,若散列函数为H(key)=key%7,并采用链地址法来解决冲突,则在等概率情况下查找成功的平均查找长度为()

h(19)=5

h(14)=0

.....

0\] \[1\] \[2\] \[3\] \[4\] \[5\] \[6

14 1 23 10 11 19 20

84 79 68 25

77

第一层比较一次就能找到,第二层比较两次能找到

所以总的查找次数为 1*7 + 2*4 + 3*1 = 18

所以平均查找长度为 18/12=1.5

相关推荐
通信小呆呆5 天前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
H__Rick5 天前
自动对焦学习-3
人工智能·学习·计算机视觉
Daisy Lee5 天前
量化学习-第1章-什么是量化金融
学习·金融·datawhale
Alsn865 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
YM52e5 天前
买菜计算器小应用 - HarmonyOS ArkUI 开发实战-PC版本
学习·华为·harmonyos·鸿蒙·鸿蒙系统
小雨下雨的雨5 天前
HarmonyOS ArkUI训练营入门-组件掌握系列-Animation 动画效果实现-PC版本
学习·华为·harmonyos·鸿蒙
cqbzcsq5 天前
CellFlow虚拟细胞论文阅读
论文阅读·人工智能·笔记·学习·生物信息
YangYang9YangYan5 天前
2026初入职场学习数据分析的价值
学习·数据挖掘·数据分析
guslegend5 天前
理论学习:什么是 Coding Agent?
学习
自传.5 天前
尚硅谷 Vibe Coding|第三章(1) Claude Code深度使用与进阶技巧 学习笔记
笔记·学习·尚硅谷·vibecoding