【数据结构】查找3——散列表(又称哈希表)的查找


散列表(又称哈希表)的基本概念

Hash:哈希
翻译为:散列、杂凑

  • 基本思想:

记录的存储位置与关键字之间存在对应关系。
对应关系——hash函数:如H(keyi)=k
Loc(i)=H(keyi)表示关键字的值是多少,存储位置就是多少。

根据散列函数H(key)=k查找:
在这里插入图片描述
优点:查找效率高
缺点:空间效率低

  • 名称概念:

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

散列函数(杂凑函数):
散列方法中使用的转换函数。
如:H(keyi)=k,H(keyi)=k/10,……

散列表(杂凑表):
按上述思想构造的表。

冲突:
不同的关键码映射到同一个散列地址。
key1≠key2,但是H(key1)=H(key2)

同义词:
具有相同函数值的多个关键字。

散列函数的构造方法

使用散列表要解决好两个问题:
(1)构造好的散列函数
(a)所选函数尽可能简单,以便提高转换速度;
(b)所选函数对关键码计算出的地址,应在散列地址集中致均匀分布,以减少空间浪费。
(2)制定一个好的解决冲突的方案
查找时,如果从散列函数计算出的地址中查不到关键码,则应当依据解决冲突的规则,有规律地查询其它相关单元。

构造散列函数考虑的因素:
①执行速度(即计算散列函数所需时间);
②关键字的长度;
③散列表的大小;(大的浪费空间但是冲突少,小的节省空间,但是冲突多)
④关键字的分布情况;(发布更加均匀)
⑤查找频率。(经常查找的可以比较容易找到)

根据元素集合的特性构造:
要求一:n个数据原仅占用n个地址,虽然散列查找是以空间换时间,但仍希望散列的地址空间尽到。
要求二:无论用什么方法存储,目的都是尽量均匀地存放元素,以避免冲突。

散列函数的构造方法:
1、直接定址法
2、数字分析法
3、平方取中法
4、折叠法
5、除留余数法(常用)
6、随机数法

直接定值法

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

优点:以关键码key的某个线性函数值为散列地址,不会产生冲突。
缺点:要占用连续地址空间,空间效率低。

在这里插入图片描述

除留余数法

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

选取合适的p:
设表长为m,取p≤m且为质数

在这里插入图片描述

处理冲突的方法

1、开放定址法(开地址法)
2、链地址法(拉链法)
3、再散列法(双散列函数法)
4、建立一个公共溢出区

开放地址法(开地址法)

基本思想:
所有位置都开放使用,有冲突时就去寻找下一个空的散列地址,只要散列表定够大,空的散列地址总能找到,并将数据元素存入。
例如:除留余数法 Hi=(Hash(key)+di) mod m(di为增量序列)

寻找下一个空的散列地址的方法:
在这里插入图片描述

线性探测法

Hi=(Hash(key)+di)mod m (1≤i<m)
其中:
m为散列表长度
di为增量序列1, 2,……m-1,且di=i
一旦冲突,就找下一个地址,直到找到空地址存入

例:
关键码集为{47, 7, 29, 11, 16, 92,22,8, 3},散列表的表长为m=11;散列函数为Hash(key)=key mod 11;拟用线性探测法解决冲突。建散列表如下:

在这里插入图片描述
解释:
① 47、7均是由散列函数得到的没有冲突的散列地址;
② Hash(29)=7,散列地址有冲突,需寻找下一个空的散列地址:
由H1=(Hash(29)+1) mod 11=8,散列地址8为空,因此将29存入。
③ 11、16、92均是由散列函数得到的没有冲突的散列地址;
④另外,22、8、3同样在散列地址上有冲突,也是由H1找到空的散列地址的。

平均查找长度ASL=(1+2+1+1+1+4+1+2+2)/9=1.67

二次探测法

例:
在这里插入图片描述
伪随机探测法:
Hi=(Hash(key)+di) mod m (1≤i<m)
其中:
m为散列表长度
di为伪随机数

链地址法

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

例如:
一组关键字为
{19,14,23,1,68,20,84,27,55,11,10,79},
散列函数为
Hash(key)=key mod 13
在这里插入图片描述

链地址法建立散列表步骤:
1、取数据元素的关键字key,计算其散列函数值(地址)。若该地址对应的链表为空,则将该元素插入此链表;否则执行下一步解决冲突。
2、根据选择的冲突处理方法,计算关键字key的下一一个存储地址。若该地址对应的链表为不为空,则利用链表的前插法或后插法将该元素插入此链表。

链地址法的优点:
① 非同义词不会冲突,无“聚集”现象;
非同义词:用同一散列函数不同参数计算出的地址相同的元素
② 链表上结点空间动态申请,更适合于表长不确定的情况。

散列表的查找效率分析

使用平均查找长度ASL来衡量查找算法,ASL取决于:
① 散列函数
② 处理冲突的方法
③ 散列表的装填因子α
α=表中填入的记录数 / 哈希表的长度
α越大,表中记录数越多,说明表装得越满,发生冲突的可能性就越大,查找时比较次数就越多。

平均查找长度ASL:
在这里插入图片描述

结论:
① 散列表技术具有很好的平均性能,优于一些传统的技术。
② 链地址法优于开地址法。( 链地址法查找效率更快;动态的,表长度容易修改;插入删除方便……)
③ 除留余数法作散列函数优于其它类型函数。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值