哈希的常规构造方法以及冲突解决

哈希表的概念

哈希表

即散列存储结构

散列法存储的基本思想

建立关键码字与其存储位置的对应关系,或者说,由关键码的值决定数据的存储地址

优点
查找速度极快 (O(1)) ,查找效率与元素个数n无关!

缺点
空间效率低

哈希方法(杂凑法)

选取某个函数,依该函数按关键字计算元素的存储位置,并按此存放;查找时,由同一个函数对给定值k计算地址,将k与地址单元中元素关键码进行比,确定查找是否成功。

哈希函数(杂凑函数)

哈希方法中使用的转换函数称为哈希函数(杂凑函数)

哈希表(杂凑表)

按上述思想构造的表称为哈希表(杂凑表)

冲突

通常关键码的集合比哈希地址集合大得多,因而经过哈希函数变换后,可能将不同的关键码映射到同一个哈希地址上,这种现象称为冲突。

哈希方法必须解决以下两个问题

构造好的哈希函数

所选函数尽可能简单,以便提高转换速度;
所选函数对关键码计算出的地址,应在哈希地址集中大致均匀分布,以减少空间浪费。

制定一个好的解决冲突的方案

查找时,如果从哈希函数计算出的地址中查不到关键码,则应当依据解决冲突的规则,有规律地查询其它相关单元。

哈希函数的构造方法

直接定址法

Hash(key)=a * key+b (a、b为常数)

优点

以关键码key的某个线性函数值为哈希地址,不会产生冲突.

缺点

要占用连续地址空间,空间效率低。

举例

R60jmD.png

除留余数法

Hash(key)=key mod p (p是一个整数)

特点

以关键码除以p的余数作为哈希地址。

关键

如何选取合适的p?

技巧

若设计的哈希表长为m,则一般取p≤m且为质数(也可以是不包含小于20质因子的合数)

数字分析法

特点

某关键字的某几位组合成哈希地址。所选的位应当是:各种符号在该位上出现的频率大致相同

举例

R6DfIJ.png

平方取中法

特点

对关键码平方后,按哈希表大小,取中间的若干位作为哈希地址

理由

因为中间几位与数据的每一位都相关


2589的平方值为6702921,可以取中间的029为地址

折叠法

特点

将关键码自左到右分成位数相等的几部分(最后一部分位数可以短些),然后将这几部分叠加求和,并按哈希表表长,取后几位作为哈希地址。

适用于

每一位上各符号出现概率大致相同的情况

移位法

将各部分的最后一位对齐相加

间界叠加法

从一端向另一端沿分割界来回折叠后,最后一位对齐相加

举例

元素42751896
移位法:427+518+96=1041
间界叠加法:427 518 96—> 724+518+69 =1311

随机数法

Hash(key)=random(key) (random为随机函数)

适用于

关键字长度不等的情况,造表和查找都很方便

构造哈希函数的原则

  1. 执行速度(即计算哈希函数所需的时间)

  2. 关键字的长度

  3. 哈希表的大小

  4. 关键字的分布情况

  5. 查找频率

解决冲突的方法

开放定址法

设计思路

有冲突时就去寻找下一个空的哈希地址,只要哈希表足够大,空的哈希地址总能找到,并将数据元素存入。

1.线性探测法

Hi=(Hash(key)+di) mod m ( 1≤i < m )

其中:
Hash(key)为哈希函数
m为哈希表长度
di 为增量序列 1,2,…m-1,且di=i(含义:一旦冲突,就找附近(下一个)空地址存入)

举例

R6ci1s.png

线性探测法的优点

只要哈希表未被填满,保证能找到一个空地址单元存放有冲突的元素

线性探测法的缺点

可能使第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²

R6gVxA.png

伪随机探测法

若di为伪随机序列,就称为伪随机探测法

链地址法(拉链法)

基本思想
将具有相同哈希地址的记录链成一个单链表,m个哈希地址就设m个单链表,然后用一个数组将m个单链表的表头指针存储起来,形成一个动态的结构。

举例

R62Lc9.png

再哈希法(双哈希函数法)

Hi=RHi(key) i=1, 2, …,k
RHi均是不同的哈希函数,当产生冲突时就计算另一个哈希函数,直到冲突不再发生。

优点

不易产生聚集

缺点

增加了计算时间

建立公共溢出区

思路

除设立哈希基本表外,另设一个溢出向量表
所有关键字和基本表中关键字为同义词的记录,不管它们由哈希函数得到的地址是什么,一旦发生冲突,都填入溢出表。

冲突是不是比较讨厌

不一定

正因为有冲突,使得文件加密后无法破译(不可逆,是单向散列函数,可用于数字签名)。

利用了哈希表性质:源文件稍稍改动,会导致哈希表变动很大。

哈希表的查找效率分析

使用平均查找长度ASL来衡量查找算法啊
ASL取决于

  • 哈希函数

  • 处理冲突的方法

  • 哈希表的装填因子α

α=表中填入的记录数/哈希表的长度

α越大,表中记录数越多,说明表装得越满,发生冲突的可能性就越大,查找时比较次数就越多。

R6WaZt.png

几点结论

对哈希表技术具有很好的平均性能,优于一些传统的技术
链地址法优于开地址法
除留余数法作哈希函数优于其它类型函数

posted @   JemmyZhong  阅读(82)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
levels of contents
点击右上角即可分享
微信分享提示