先理解静态Hash法中几个概念:Hash表,桶、槽、关键字、Hash地址。
Hash表:把辞典中的词条二元组存储到表*ht*中,这个表称为Hash表。
桶(bucket) 和 槽(slot):
Hash表分成*b* 个桶,*ht[0]*,...,*ht[b-1]*,每个桶可分*s*个槽,每个槽可存放一条词条。
Hash地址:
每个槽的地址或位置,由一个关于该词条关键字k的Hash函数h计算得到,h把关键字k映射到一个桶号。 对于关键字k, h(k)是一个整数,取值范围是[0,b-1],称*h[k]*是k的Hash地址。
Hash表的关键字密度:
n/T , 其中n是存放在Hash表中的词条数目,T是所有关键字数目。
Hash表的装填密度:
n/(s*b)
桶溢出:
当一条新词条试图放入某桶中时,该桶已满,此时称为桶溢出。
关键字冲突:
当一条新词条试图放入某桶中时,该桶已不空,此时称为关键字冲突。 当每桶只有一槽时,则溢出发生时冲突也同时发生,反之亦然。
概念间联系:
Hash法用Hash函数把关键字映射到Hash表的桶中,Hash函数的设计原则是既要便于计算又要尽量避免冲突。
由于关键字空间的基数远远大于表中桶数,而且桶中槽数又很小,因此无法避免冲突,所以必须要研究处理溢出的方法。
Hash函数:
把关键字映射到Hash表的桶里。Hash函数输入时关键字,输出是对应的Hash表的桶的桶号。
一致映射Hash函数:
在关键字空间随机选取的关键字k, h应把k等概率地映射到桶号i, 即h(k) = i的概率是1/b, 使每个关键字映射到任意一个桶号的机会相等。
满足一致概率分布的Hash函数称为一致映射Hash函数。
概念联系:
通常利用关键字做算术运算,取其结果表示桶号的方法构造Hash函数。字符串类的关键字无法直接进行算术运算,
可事先将关键字转换成另一种形式,如整数再做算术运算得到映射结果。下面介绍常用的Hash函数构造方法。
余数法:
设关键字是非负整数,余数法对关键字求余,其结果是地址桶号。令关键字是k, 除以某数D, 余数作为k的地址桶号,函数如下:
h(k) = k mod D
这个函数得出的桶地址范围是[0,D-1], 因而Hash表至少必须有b=D个桶。尽管对于大多数关键字空间来说,
实践证明:只要D中的最小素因子不小于20,多数辞典的关键字可以相当均匀地映射到所需桶号范围之内。
平方取中法:
该方法的Hash函数取关键字平方值的中间某几位做桶地址,要求关键是整数。
因为关键字的平方值与关键字的所有位相关,即使某几位相同,平方后取中间即为,不同关键字将以高概率映射到不同地址。
在关键字的平方值中取位的数目将确定表的长度,若取r位,则Hash地址范围是0~pow(2, r)-1,因此采用平方取中法的Hash表,其表长应是2的幂。
折叠法:
把关键字k分解成长度相等的几段(最右面一段可能不相等),再把各段加起来做Hash地址h(k)。
各段相加的方法有两种,一种是把分解的各段向右对齐相加,这种做法称为平移折叠法;另一种叫边界对齐折叠,
即把每段首尾对齐折叠起来,也就是把奇数段按位顺序变反后再与后续邻接到偶数段相加。
例:以关键字k=12320324111220为例,先把它分为每段3为十进制位,P1=123,P2=203,P3=241,P4=112,P5=20。
平移折叠法得到:h(k) = 123 + 203 + 241 + 112 + 20 = 699.
边界对齐折叠法得到:h(k) = 123 + 302 + 241 + 211 + 20 = 897.
数字分析法: