哈希表(散列表)及哈希表处理冲突的方法 | 您所在的位置:网站首页 › 日本首相有坐牢的么 › 哈希表(散列表)及哈希表处理冲突的方法 |
前面介绍了静态查找表以及动态查找表中的一些查找方法,其查找的过程都无法避免同查找表中的数据进行比较,查找算法的效率很大程度取决于同表中数据的查找次数。
而本节所介绍的哈希表可以通过关键字直接找到数据的存储位置,不需要进行任何的比较,其查找的效率相较于前面所介绍的查找算法是更高的。
哈希表的构建
在初中的数学课本中学习过函数的相关知识,给定一个 x,通过一个数学公式,只需要将 x 的值带入公式就可以求出一个新的值 y。
哈希表的建立同函数类似,把函数中的 x 用查找记录时使用的关键字来代替,然后将关键字的值带入一个精心设计的公式中,就可以求出一个值,用这个值来表示记录存储的哈希地址。即:
数据的哈希地址=f(关键字的值)
哈希地址只是表示在查找表中的存储位置,而不是实际的物理存储位置。f()是一个函数,通过这个函数可以快速求出该关键字对应的的数据的哈希地址,称之为“哈希函数”。 例如,这里有一个电话簿(查找表),电话簿中有 4 个人的联系方式: 张三 13912345678 李四 15823457890 王五 13409872338 赵六 13805834722 假如想查找李四的电话号码,对于一般的查找方式最先想到的是从头遍历,一一比较。而如果将电话簿构建成一张哈希表,可以直接通过名字“李四”直接找到电话号码在表中的位置。 在构建哈希表时,最重要的是哈希函数的设计。例如设计电话簿案例中的哈希函数为:每个名字的姓的首字母的 ASCII 值即为对应的电话号码的存储位置。这时会发现,张三和赵六两个关键字的姓的首字母都是 Z ,最终求出的电话号码的存储位置相同,这种现象称为冲突。在设计哈希函数时,要尽量地避免冲突现象的发生。对于哈希表而言,冲突只能尽可能地少,无法完全避免。 哈希函数的构造 常用的哈希函数的构造方法有 6 种:直接定址法、数字分析法、平方取中法、折叠法、除留余数法和随机数法。 直接定址法:其哈希函数为一次函数,即以下两种形式: H(key)= key 或者 H(key)=a * key + b 其中 H(key)表示关键字为 key 对应的哈希地址,a 和 b 都为常数。 例如有一个从 1 岁到 100 岁的人口数字统计表,如表 1 所示:![]() ![]() ![]() 在此方法中,对于 p 的取值非常重要,由经验得知 p 可以为不大于 m 的质数或者不包含小于 20 的质因数的合数。 随机数法:是取关键字的一个随机函数值作为它的哈希地址,即:H(key)=random(key),此方法适用于关键字长度不等的情况。 注意:这里的随机函数其实是伪随机函数,随机函数是即使每次给定的 key 相同,但是 H(key)都是不同;而伪随机函数正好相反,每个 key 都对应的是固定的 H(key)。 如此多的构建哈希函数的方法,在选择的时候,需要根据实际的查找表的情况采取适当的方法。通常考虑的因素有以下几方面: 关键字的长度。如果长度不等,就选用随机数法。如果关键字位数较多,就选用折叠法或者数字分析法;反之如果位数较短,可以考虑平方取中法; 哈希表的大小。如果大小已知,可以选用除留余数法; 关键字的分布情况; 查找表的查找频率; 计算哈希函数所需的时间(包括硬件指令的因素) 处理冲突的方法 对于哈希表的建立,需要选取合适的哈希函数,但是对于无法避免的冲突,需要采取适当的措施去处理。 通常用的处理冲突的方法有以下几种: 开放定址法 H(key)=(H(key)+ d)MOD m(其中 m 为哈希表的表长,d 为一个增量) 当得出的哈希地址产生冲突时,选取以下 3 种方法中的一种获取 d 的值,然后继续计算,直到计算出的哈希地址不在冲突为止,这 3 种方法为: 线性探测法:d=1,2,3,…,m-1 二次探测法:d=12,-12,22,-22,32,… 伪随机数探测法:d=伪随机数 例如,在长度为 11 的哈希表中已填写好 17、60 和 29 这 3 个数据(如图 2(a) 所示),其中采用的哈希函数为:H(key)=key MOD 11,现有第 4 个数据 38 ,当通过哈希函数求得的哈希地址为 5,与 60 冲突,则分别采用以上 3 种方式求得插入位置如图 2(b)所示:![]() ![]() 哈希表实现查找操作的具体实现下节有详细介绍。 |
CopyRight 2018-2019 实验室设备网 版权所有 |