教你几招HASH表查找的方法
摘要:根据设定的哈希函数 H(key) 和所选中的处理冲突的方法,将一组关键字映象到一个有限的、地址连续的地址集 (区间) 上,并以关键字在地址集中的“象”作为相应记录在表中的存储位置,如此构造所得的查找表称之为“哈希表”。
本文分享自华为云社区《查找——HASH》,原文作者:ruochen。
对于频繁使用的查找表,希望 ASL = 0
记录在表中位置和其关键字之间存在一种确定的关系
HASH
定义
根据设定的哈希函数 H(key) 和所选中的处理冲突的方法,将一组关键字映象到一个有限的、地址连续的地址集 (区间) 上,并以关键字在地址集中的“象”作为相应记录在表中的存储位置,如此构造所得的查找表称之为“哈希表”
HASH函数的构造
- 构造原则
- 函数本身便于计算
- 计算出来的地址分布均匀,即对任一关键字k,f(k) 对应不同地址的概率相等,目的是尽可能减少冲突
直接定址法
- 哈希函数为关键字的线性函数
- H(key) = key
- H(key) = a * key + b
- 此法仅适合于:
地址集合的大小 = = 关键字集合的大小 - 优点:以关键码key的某个线性函数值为哈希地址,不会产生冲突
- 缺点:要占用连续地址空间,空间效率低
数字分析法
- 假设关键字集合中的每个关键字都是由 s 位数字组成 (u1, u2, …, us),分析关键字集中的全体, 并从中提取分布均匀的若干位或它们的组合作为地址
- 此方法仅适合于:
能预先估计出全体关键字的每一位上各种数字出现的频度
平方取中法
- 以关键字的平方值的中间几位作为存储地址。求“关键字的平方值” 的目的是“扩大差别” ,同时平方值的中间各位又能受到整个关键字中各位的影响
- 此方法适合于:
关键字中的每一位都有某些数字重复出现频度很高的现象
折叠法
- 将关键字分割成若干部分,然后取它们的叠加和为哈希地址。有两种叠加处理的方法:移位叠加和间界叠加
- 此方法适合于:
关键字的数字位数特别多
除留余数法
- Hash(key)=key mod p (p是一个整数)
- p≤m (表长)
- p 应为小于等于 m 的最大素数
为什么要对 p 加限制?
给定一组关键字为: 12, 39, 18, 24, 33, 21若取 p=9, 则他们对应的哈希函数值将为:
3, 3, 0, 6, 6, 3
可见,若 p 中含质因子 3, 则所有含质因子 3 的关键字均映射到“3 的倍数”的地址上,从而增加了“冲突”的可能
随机数法
- H(key) = Random(key) (Random 为伪随机函数)
- 此方法用于对长度不等的关键字构造哈希函数
考虑因素
- 执行速度(即计算哈希函数所需时间)
- 关键字的长度
- 哈希表的大小
- 关键字的分布情况
- 查找频率
采用何种构造哈希函数的方法取决于建表的关键字集合的情况
原则是使产生冲突的可能性降到尽可能地小
处理冲突的方法
1. 开放定址法
基本思想
- 有冲突时就去寻找下一个空的哈希地址,只要哈希表足够大,空的哈希地址总能找到,并将数据元素存入
线性探测法
- Hi=(Hash(key)+di) mod m ( 1≤i < m )
其中:m为哈希表长度
di 为增量序列 1,2,…m-1,且di=i
一旦冲突,就找下一个空地址存入
- 优点:只要哈希表未被填满,保证能找到一个空地址单元存放有冲突的元素
- 缺点:能使第i个哈希地址的同义词存入第i+1个地址,这样本应存入第i+1个哈希地址的元素变成了第i+2个哈希地址的同义词,……,产生“聚集”现象,降低查找效率
二次探测法
di = 12, -12, 22, -22, …±k2
伪随机探测法
Hi=(Hash(key)+di) mod m ( 1≤i < m )
其中:m为哈希表长度
di 为随机数
开放定址法建立哈希表步骤
- 取数据元素的关键字key,计算其哈希函数值(地址)。若该地址对应的存储 空间还没有被占用,则将该元素存入;否则执行step2解决冲突
- 根据选择的冲突处理方法,计算关键字key的下一个存储地址。若下一个存储地址仍被占用,则继续执行step2,直到找 到能用的存储地址为止
开放定址哈希表的存储结构
/* ------------- 开放定址哈希表的存储结构 ------------- */int hashsize[] = {997, ...};
typedef struct{ElemType* elem;int count; // 当前数据元素个数int sizeindex; // hashsize[sizeindex]为当前容量
} HashTable;#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1Status SearchHash(HashTable H, KeyType K, int &p, int &c){// 在开放定址哈希表H中查找关键码为K的记录p = Hash(K); // 求得哈希地址while(H.elem[p].key != NULLKEY && !EQ(K, H.elem[p].key))collisiion(p, ++c); // 求得下一探测地址pif(EQ(K, H.elem[p].key)) return SUCCESS; // 查找成功,返回待查数据元素位置 pelse return UNSUCCESS; // 查找不成功
}
2. 再HASH法
- H2(key) 是另设定的一个哈希函数,它的函数值应和 m 互质
3. 链地址法
基本思想
- 相同哈希地址的记录链成一单链表,m个哈希地址就设m个单链表,然后用用一个数组将m个单链表的表头指针存储起来,形成一个动态的结构
优点:
- 非同义词不会冲突,无“聚集”现象
- 链表上结点空间动态申请,更适合于表长不确定的情况
哈希表的查找
对于给定值 K,计算哈希地址 i = H(K)
- 若 r[i] = NULL 则查找不成功
- 若 r[i].key = K 则查找成功, 否则 “求下一地址 Hi” ,直至r[Hi] = NULL (查找不成功) 或r[Hi].key = K (查找成功) 为止
案例v01
- 线性探测法解决冲突
案例v02
- 链地址法处理冲突
哈希表查找的分析
从查找过程得知,哈希表查找的平均查找长度实际上并不等于零
决定哈希表查找的ASL的因素
- 选用的哈希函数
- 选用的处理冲突的方法
- 哈希表饱和的程度,装载因子 α=n/m 值的大小(n—记录数,m—表的长度)
α 越大,表中记录数越多,说明表装得越满,发生冲突的可能性就越大,查找时比较次数就越多
- 对哈希表技术具有很好的平均性能,优于一些传统的技术
- 链地址法优于开地址法
- 除留余数法作哈希函数优于其它类型函数
哈希表应用举例
编译器对标识符的管理多是采用哈希表
- 构造哈希函数的方法
- 将标识符中的每个字符转换为一个非负整数
- 将得到的各个整数组合成一个整数(可以将第一个、中间的和最后一个字符值加在一起,也可以将所有字符的值加起来)
- 将结果数调整到0~M-1范围内,可以利用取模的方法,Ki%M(M为素数)
点击关注,第一时间了解华为云新鲜技术~
教你几招HASH表查找的方法相关推荐
- hash表冲突处理方法
为提高hash表查找性能,除了考虑选择合适的hash表表长和完美的hash函数外,还必须考虑hash表处理冲突的能力.当hash函数对两个不同的数据项产生了相同的hash值时,冲突就产生了.对于冲突的 ...
- 哈希(hash)表查找速度为什么那么快?快在哪里了?
先看数组存储数据是怎么样的. 现在有一个数组,它里面每个单元存储的是数据的地址 这叫指针数组吧,假设它有100个单元 我们称他为p[100] 现在我想把一百个数据(地址)放到里面 我们想把某个数据放到 ...
- Hash表查找成功和查找不成功的平均查找长度(附总结)
Hash表的平均查找长度包括查找成功时的平均查找长度和查找失败时的平均查找长度. 查找成功时的平均查找长度=表中每个元素查找成功时的比较次数之和/表中元素个数: 查找不成功时的平均查找长度相当于在表中 ...
- 教你九招防电脑辐射的方法!
第一招:在电脑旁放上几盆仙人掌,它可以有效地吸收辐射 ; 第二招: 还对于生活紧张而忙碌的人群来说,抵御电脑辐射最简单的办法就是在每天上午喝 2 至 3 杯的绿茶,吃一个橘子.茶叶中含有丰富的维生素A ...
- 怎么将图片压缩到50k以内?教你一招将图片缩小的方法
很多职业每天都会使用到大量的图片,在我们上传使用图片的过程中,有时会遇到图片上传的大小要在50kb以内的情况.那么在遇到这种情况的时候,我们应该怎样才能将图片压缩到指定的大小呢?别急,接下来小编就为大 ...
- 什么邮箱最安全?教你三招快速提升邮箱安全性方法,职场人必看!
电子邮箱常以正式.专业的形象出现在日常工作及生活中.人们对其使用频率越高随之而来的担忧越多,如账号被盗.邮箱频收非正常邮件.资料丢失等.今天小编要向大家分享如何快速升级邮箱性能的方法,快学起来吧! 一 ...
- 证件照怎么弄?教你一招制作证件照的简单方法
我们现在找工作或者是参加各种考试的时候都需要用到证件照,不同的地方对证件照的要求也不同,因为某些原因不方便去照相馆的时候怎么能自己制作一张证件照呢?别急,接下来我给大家推荐一款在线照片制作(https ...
- win10计算机怎样双屏,有什么办法让window10双屏显示_教你一招让window10双屏的方法...
win10电脑运行多个程序会不知不觉打开多个不同类型的窗口,窗口多了总要时不时的来回频繁切换,总感觉很麻烦.如果不想频繁切换,我们可以让window10双屏显示,而且win10系统双屏显示设置步骤并不 ...
- 动态gif图片怎么做?教你一招gif在线制作的方法
想要将手中的图片制作成有动态效果的gif动图时,使用[gif5工具网]的在线动图制作(https://www.gif5.net/)功能就能快速解决这个问题.步骤非常简单,只需要上传jpg.png以及g ...
最新文章
- Postgres-XL:基于PostgreSQL的开源可扩展数据库集群
- 不得不爱开源 Wijmo jQuery 插件集(4)-【手风琴效果】(附页面展示和源码)
- 在机器学习分类中如何处理训练集中不平衡问题
- boost::geometry::strategy::distance::cross_track用法的测试程序
- CSharp设计模式读书笔记(18):中介者模式(学习难度:★★★☆☆,使用频率:★★☆☆☆)...
- PowerDesiGner数据库设计
- Spring的AOP-底层原理
- 【树莓派】Raspbian 中国软件镜像源
- 基于JAVA+SpringMVC+Mybatis+MYSQL的线上电器商城
- Android异常总结---E/AndroidRuntime(23439): Caused by: java.lang.IllegalArgumentException: column '_id' d
- mac 本地安装mysql_mac 本地安装mysql服务
- 1400协议是什么和28181区别_gb28181协议常见流程简析
- html设置ie兼容性视图,如何用脚本配置IE兼容性视图设置
- 通过调用接口查询ISBN的图书信息
- 组合学:使用10个数字与52个字母生成1477万个不重复的4位串码V3完结版本
- 【XSY2495】余数
- 图解向量场、散度、旋度(二维平面)
- 使用C语言开发web
- 投资理财-如何避免亏损
- 代换密码详解+CTF事例
热门文章
- 晶体(crystal)和晶振(oscillator)的区别
- Microsoft SQL Server 数据库使用(二)
- 快速调整毕业论文格式:调整参考文献的引用样式和段落格式
- 笔记本重装系统如何找回之前自己自带的office
- 二进制和 四,八,十,十六,三十二进制的转换
- c#语言-正方形,圆形,利用接口实现周长及面积的计算
- vasp能装在window系统里吗_Window安装系统详解
- 棒球·飞盘·MLB棒球创造营
- go+gSoap+onvif学习总结:7、进行镜头调焦、聚焦和预置点的增删改查
- 单元测试之moles