哈希表查找(简单理解)

 哈希表的查找过程与哈希表的创建过程是一致的。

散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做哈希函数,存放记录的数组称做哈希表

我一般是用除数余留法对关键字的地址进行分配。

除数余留法

除数余留法是假设哈希表长为m,p是小于等于m的最小素数,则哈希函数为:H(K)=k%p。H(k)是计算哈希地址的。

虽然这样可以求出关键字的哈希地址,但是这时会产生冲突,导致多个关键字进入到一个地址中。

这是我们就要尽量减少冲突的发生,减少冲突的方法有多个,我们这里学习开放地址的法链地址法

链地址法

将所有关键字为同义词的记录存储在同一线性单链表中,我们称这种表为同义词子表,在哈希表中只存储所有同义词子表的头指针。

 例:

已知一组关键字分别为(32,40,36,53,16,46,71,27,42,24,49,64),哈希表长度为13.

由此可知哈希函数为H(k)=k%13.这时我们要利用哈希函数将关键字的哈希地址算出并填入下表中。

由公式我们可以很容易算出上面关键字的地址,将他们写入下表中,如下图所示。 

   

这时我们也可以得出哈希表的平均查找长度ASL

ASL=(比较的次数*关键字的个数)/关键字总共的个数=(1*7+2*4+3*1)/12=1.5         

开放地址法

开放地址法会根据当前的位置计算出下一个位置,将这个冲突的元素挪进来。 如果这下一个位置也被占用了,那么就再计算下一个位置,直到找到一个空的位置。 可以想像,将会有一条虚拟的链条将这些相关的位置串起来。 这个虚拟的链条就好比开链法里面的第二维链表。

开放地址法的公式为:

hi=(h0+di)%m.

h0=H(key)是哈希函数,di为增量序列,m为表长,hi为算出的地址。

 

增量序列的取值不同,相应的再散列方式也不同。主要有三种方式,这里给出两种散列方式,线性探测再散列和二次探测再散列。

 线性探测再散列

di=1,2,3,4.......m-1

这种方法的特点是当冲突发生时,顺序查看表中的下一个单元,直至查找到一个空单元或全表。

已知一组关键字分别为(32,40,36,53,16,46,71,27,42,24,49,64),哈希表长度为13.

0123456789101112

由公式H(k)=k%p,可知H(32)=32%13=6 填入到表中

0123456789101112
32

由公式H(k)=k%p,可知H(40)=40%13=1 填入到表中 

0123456789101112
4032

 由公式H(k)=k%p,可知H(36)=36%13=10 填入到表中 

 

0123456789101112
403236

 由公式H(k)=k%p,可知H(53)=53%13=1,这时发现冲突,利用公式hi=(h0+di)%m,将53的哈希地址向后移动一位。

0123456789101112
40533236

接下来就按这种方式依次将哈希地址算出,将关键字放到各自的哈希地址上。

0123456789101112
644053162742324671362449
二次探测再散列

d=1(^2),-1(^2),2(^2),-2(^2).....k(^2),-k(^2)         (k<=m/2)

这种方法的特点是,当冲突发生时,在表的左右跳跃式探测,比较灵活。

大家可以用上面的例子或其他的例子在下面试一试。

 

                                                             

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值