- 概念:哈希表是一种以键–值存储的数据结构。(key-indexed)目的:输入待查找的值(key),查找到它对应的值。
2.哈希查找步骤:
(1)使用哈希函数将被查找的键转换为数组的索引。(不同的键会被转换为不同的索引值理想情况下)
(2)处理哈希碰撞冲突。
如果没有内存限制,则直接可以将键值作为数组的索引。查找时间的复杂度为O(1)
如果没有时间限制,则可以使用无序数组进行顺序查找。只需要很少的内存。哈希表就是要在适度的时间和空间上进行两个极端的平衡。 - 在Hash表中:本质就是记录在表中的位置和其关键字直接存在着一种确定的关系
(1)哈希函数是一个映像(将关键字的集合映射到某个地址集合上,但是地址集合不能超过允许范围)
(2)一般情况下,容易产生冲突现象(key1!=key2但是f(key1)=f(key2))
(3)不能完全避免冲突,但是可以减少冲突。(地址集合的元素仅为哈希表中的地址值) - 介绍Hash构造的方法
在其他博客上收集几种比较容易理解的方法。[一个非常详细的hash构造函数的博客]
(https://blog.youkuaiyun.com/tanggao1314/article/details/51457585)
(1)数字分析法:
假设关键字集合中的每个关键字都是由 s 位数字组成 (u1, u2, …, us),分析关键字集中的全体,并从中提取分布均匀的若干位或它们的组合作为地址。
例子1:要构造一个数据元素个数n=80,哈希长度m=100的哈希表。不失一般性,我们这里只给出其中8个关键字进行分析,8个关键字如下所示
K1=61317602 K2=61326875 K3=62739628 K4=61343634
K5=62706815 K6=62774638 K7=61381262 K8=61394220
分析上述8个关键字可知,关键字从左到右的第1、2、3、6位取值比较集中,不宜作为哈希地址,剩余的第4、5、7、8位取值较均匀,可选取其中的两位作为哈希地址。设选取最后两位作为哈希地址,则这8个关键字的哈希地址分别为:2,75,28,34,15,38,62,20。
此法适于:能预先估计出全体关键字的每一位上各种数字出现的频度。
(2)折叠法:将关键字分割成若干部分,然后取它们的叠加和为哈希地址。**折叠法是将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位),这方法称为折叠法。这种方法适用于关键字位数较多,而且关键字中每一位上数字分布大致均匀的情况。
折叠法中数位折叠又分为移位叠加和边界叠加两种方法,移位叠加是将分割后是每一部分的最低位对齐,然后相加;边界叠加是从一端向另一端沿分割界来回折叠,然后对齐相加**。
例子2,当哈希表长为1000时,关键字key=110108331119891,允许的地址空间为三位十进制数,则这两种叠加情况如图:
移位叠加 边界叠加
8 9 1 8 9 1
1 1 9 9 1 1
3 3 1 3 3 1
1 0 8 8 0 1
1 1 0 1 1 0
+ +
(1) 5 5 9 (3) 0 4 4
用移位叠加得到的哈希地址是559,而用边界叠加所得到的哈希地址是44。如果关键字不是数值而是字符串,则可先转化为数。转化的办法可以用ASCⅡ字符或字符的次序值;**此法适于:关键字的数字位数特别多**。
(3)除留余数法:
假设哈希表长为m,p为小于等于m的最大素数,则哈希函数为h(k)=k%p ,其中%为模p取余运算。
例子3,已知待散列元素为(18,75,60,43,54,90,46),表长m=10,p=7,则有
h(18)=18 % 7=4 h(75)=75 % 7=5 h(60)=60 % 7=4
h(43)=43 % 7=1 h(54)=54 % 7=5 h(90)=90 % 7=6
h(46)=46 % 7=4
此时冲突较多。为减少冲突,可取较大的m值和p值,如m=p=13,结果如下:
h(18)=18 % 13=5 h(75)=75 % 13=10 h(60)=60 % 13=8
h(43)=43 % 13=4 h(54)=54 % 13=2 h(90)=90 % 13=12
h(46)=46 % 13=7
此时没有冲突,结果如下图所示(在上机笔试时遇到过)。
理论研究表明,除留余数法的模p取不大于表长且最接近表长m素数时效果最好,且p最好取1.1n~1.7n之间的一个素数(n为存在的数据元素个数)。
(4)旋转法:旋转法是将数据的键值中进行旋转。旋转法通常并不直接使用在哈希函数上,而是结合其他哈希函数使用。
例子4:,某学校同一个系的新生(小于100人)的学号前5位数是相同的,只有最后2位数不同,我们将最后一位数,旋转放置到第一位,其余的往右移。运用这种方法可以只输入一个数值从而快速地查到有关学生的信息。
总结:还有其他hash函数构造的方法,具体详情可以参考下面的连接。要根据不同的实际情况,采用灵活的方法。主要考虑以下的几个因素:
(1)哈希函数所需时间(2)哈希表大小,关键字长度(3)关键字分布和查找频率。
还有一些其他构造方法:字符串数值哈希法,随机乘数法,基数转换法,减去法,平方取中法,直接定址法等。详细hash构造函数方法