哈希的常规构造方法以及冲突解决
哈希表的概念
哈希表
即散列存储结构
散列法存储的基本思想
建立关键码字与其存储位置的对应关系,或者说,由关键码的值决定数据的存储地址
优点
查找速度极快 (O(1)) ,查找效率与元素个数n无关!
缺点
空间效率低
哈希方法(杂凑法)
选取某个函数,依该函数按关键字计算元素的存储位置,并按此存放;查找时,由同一个函数对给定值k计算地址,将k与地址单元中元素关键码进行比,确定查找是否成功。
哈希函数(杂凑函数)
哈希方法中使用的转换函数称为哈希函数(杂凑函数)
哈希表(杂凑表)
按上述思想构造的表称为哈希表(杂凑表)
冲突
通常关键码的集合比哈希地址集合大得多,因而经过哈希函数变换后,可能将不同的关键码映射到同一个哈希地址上,这种现象称为冲突。
哈希方法必须解决以下两个问题
构造好的哈希函数
所选函数尽可能简单,以便提高转换速度;
所选函数对关键码计算出的地址,应在哈希地址集中大致均匀分布,以减少空间浪费。
制定一个好的解决冲突的方案
查找时,如果从哈希函数计算出的地址中查不到关键码,则应当依据解决冲突的规则,有规律地查询其它相关单元。
哈希函数的构造方法
直接定址法
Hash(key)=a * key+b (a、b为常数)
优点
以关键码key的某个线性函数值为哈希地址,不会产生冲突.
缺点
要占用连续地址空间,空间效率低。
举例
除留余数法
Hash(key)=key mod p (p是一个整数)
特点
以关键码除以p的余数作为哈希地址。
关键
如何选取合适的p?
技巧
若设计的哈希表长为m,则一般取p≤m且为质数(也可以是不包含小于20质因子的合数)
数字分析法
特点
某关键字的某几位组合成哈希地址。所选的位应当是:各种符号在该位上出现的频率大致相同
举例
平方取中法
特点
对关键码平方后,按哈希表大小,取中间的若干位作为哈希地址
理由
因为中间几位与数据的每一位都相关
例
2589的平方值为6702921,可以取中间的029为地址
折叠法
特点
将关键码自左到右分成位数相等的几部分(最后一部分位数可以短些),然后将这几部分叠加求和,并按哈希表表长,取后几位作为哈希地址。
适用于
每一位上各符号出现概率大致相同的情况
移位法
将各部分的最后一位对齐相加
间界叠加法
从一端向另一端沿分割界来回折叠后,最后一位对齐相加
举例
元素42751896
移位法:427+518+96=1041
间界叠加法:427 518 96—> 724+518+69 =1311
随机数法
Hash(key)=random(key) (random为随机函数)
适用于
关键字长度不等的情况,造表和查找都很方便
构造哈希函数的原则
-
执行速度(即计算哈希函数所需的时间)
-
关键字的长度
-
哈希表的大小
-
关键字的分布情况
-
查找频率
解决冲突的方法
开放定址法
设计思路
有冲突时就去寻找下一个空的哈希地址,只要哈希表足够大,空的哈希地址总能找到,并将数据元素存入。
1.线性探测法
Hi=(Hash(key)+di) mod m ( 1≤i < m )
其中:
Hash(key)为哈希函数
m为哈希表长度
di 为增量序列 1,2,…m-1,且di=i(含义:一旦冲突,就找附近(下一个)空地址存入)
举例
线性探测法的优点
只要哈希表未被填满,保证能找到一个空地址单元存放有冲突的元素
线性探测法的缺点
可能使第i个哈希地址的同义词存入第i+1个哈希地址,这样本应存入第i+1个哈希地址的元素变成了第i+2个哈希地址的同义词,……,
因此,可能出现很多元素在相邻的哈希地址上“堆积”起来,大大降低了查找效率
二次探测法
Hi=(Hash(key)±di) mod m
其中:Hash(key)为哈希函数
m为哈希表长度,m要求是某个4k+3的质数;
di为增量序列 1²,-1²,2²,-2²,…,q²
伪随机探测法
若di为伪随机序列,就称为伪随机探测法
链地址法(拉链法)
基本思想
将具有相同哈希地址的记录链成一个单链表,m个哈希地址就设m个单链表,然后用一个数组将m个单链表的表头指针存储起来,形成一个动态的结构。
举例
再哈希法(双哈希函数法)
Hi=RHi(key) i=1, 2, …,k
RHi均是不同的哈希函数,当产生冲突时就计算另一个哈希函数,直到冲突不再发生。
优点
不易产生聚集
缺点
增加了计算时间
建立公共溢出区
思路
除设立哈希基本表外,另设一个溢出向量表
所有关键字和基本表中关键字为同义词的记录,不管它们由哈希函数得到的地址是什么,一旦发生冲突,都填入溢出表。
冲突是不是比较讨厌
不一定
正因为有冲突,使得文件加密后无法破译(不可逆,是单向散列函数,可用于数字签名)。
利用了哈希表性质:源文件稍稍改动,会导致哈希表变动很大。
哈希表的查找效率分析
使用平均查找长度ASL来衡量查找算法啊
ASL取决于
-
哈希函数
-
处理冲突的方法
-
哈希表的装填因子α
α=表中填入的记录数/哈希表的长度
α越大,表中记录数越多,说明表装得越满,发生冲突的可能性就越大,查找时比较次数就越多。
几点结论
对哈希表技术具有很好的平均性能,优于一些传统的技术
链地址法优于开地址法
除留余数法作哈希函数优于其它类型函数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!