数据结构 08 - Hash查找

使用Hash查找,首先要创建一张Hash表。

  • Hash表,又叫做散列表,是根据给定的关键字来计算出关键字在表中的地址的数据结构。也就是说,Hash表建立了关键字(自变量)和存储地址(应变量)之间的一种直接映射关系。

如何建立它们之间的关系?还有这种关系一定是一对一的吗?

hash表表长应该多大?

装填因子
hash表的装填因子一般记作 α,可以理解为一个表的装满程度
α = (表中记录数n) / (hash表长m)
α 一般在 0.7~0.8之间
所以一般设 hash表长 m = n/α

Hash表创建的两个主要问题:Hash函数的构造冲突的解决

  • Hash函数:一个把查找表中的关键字映射成该关键字对应的地址的函数,
    记作Hash(key)=Addr;
  • Hash函数可能会把两个或以上的不同关键字映射到同一地址,称这种情况为“冲突”,这些发生碰撞的不同关键字成为同义词

常用的Hash函数构造方法

直接地址法
直接取关键字的某个线性函数值为hash地址
H(key) = a*key + b

保留除数法(除留余数法)
假定hash表长m,取一个不大于m但最接近或等于m的质数p
H(key) = key % p
该方法的关键在于选好p,尽可能减少冲突的可能性

平方取中法
取关键字的平方值的中间几位作为hash地址。具体取多少根据实际情况而定。
eg.
12342 = 1522756,取中间三位227作为hash地址
23452 = 5499025,取中间三位990最为hash地址

叠加法
将关键字分割成位数相同的几部分(最后一部分的位数可能短一些),然后取这几部分的叠加和作为hash地址。
eg.
关键字 1234567890,设hash表表长为3位,则将关键字分为4组
123 | 456 | 789 | 0 ,然后求叠加和 123+456+789+0 = 1368,取后3位368作为hash地址

常用的处理冲突的方法:

开放地址法
将产生冲突的hash地址作为自变量,通过某种冲突解决函数得到一个新的空闲的hash地址。

  • ①线性探查法
    发生冲突时,顺序查看表中下一个单元,直到找出一个空闲单元。

eg. H(key) = key % 8

下标 0 1 2 3 4 5 6 7 8
key 9 10 11 19 27
  • ②二次探查法(平方探查法)
    设发生冲突的地址位d,平方探测法得到的新的地址序列位d+12,d-12,d+22,d-22

eg. H(key) = key % 8

下标 0 1 2 3 4 5 6 7 8
key 9 10 11 19 27

链地址法
发生冲突时,将具有相同hash地址的对象以链表的形式存储,通过对象内部的指针可以查询到下一个具有相同hash地址的对象。简单说就是,将产生冲突的值以链表的形式连起来。

Hash查找的过程

  1. 给定带查找的关键字key
  2. 根据hash函数计算出hash地址,检测该位置有无数据
  • 没有,表明该关键字不存在,返回失败
  • 有,检测该数据是否等于key
    • 等于,返回key所在位置
    • 不等于,按照给定的冲突处理方法计算下一个hash地址,再去执行上述过程

这里使用保留除数法构建Hash表,使用线性探查法处理冲突。
程序运行结果:
在这里插入图片描述

实现代码:

#
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值