散列表的意义

直接寻址表需要申请全域U大小的空间来存储数据,其中全域U中的有效数据集合为K,那么其存储情况如下图

而如果利用散列函数h,将全域U的值映射到h(U)->{0, 1, 2, 3 ... m - 1},则可以缩小存储空间,如下图

 

冲突

如上图,k2和k5发生了冲突,解决冲突的方法有如下几种

1.链接法,如下图

2.开放寻址法(一下内容抄自百科)

①线性探查法(Linear Probing)

  该方法的基本思想是:将散列表T[0..m-1]看成是一个循环向量,若初始探查的地址为d(即h(key)=d),则最长的探查序列为:d,d+l,d+2,…,m-1,0,1,…,d-1 .即:探查时从地址d开始,首先探查T[d],然后依次探查T[d+1],…,直到T[m-1],此后又循环到T[0],T[1],…,直到探查到T[d-1]为止。探查过程终止于三种情况:

  (1)若当前探查的单元为空,则表示查找失败(若是插入则将key写入其中);

  (2)若当前探查的单元中含有key,则查找成功,但对于插入意味着失败;

  (3)若探查到T[d-1]时仍未发现空单元也未找到key,则无论是查找还是插入均意味着失败(此时表满)。

  利用开放地址法的一般形式,线性探查法的探查序列为:

  h i =(h(key)+i)%m 0≤i≤m-1 //即d i =i

  hi=(h(key)+di) mod m i=1,2,...,k(k<=m-1)

  其中m为表长,di为增量序列

  如果di值可能为1,2,3,...m-1,称线性探测再散列。

  如果di取值可能为1,-1,2,-2,4,-4,9,-9,16,-16,...k*k,-k*k(k<=m/2)

  称二次探测再散列。

  如果di取值可能为伪随机数列。称伪随机探测再散列。开放地址法堆装填因子的要求

  开放定址法要求散列表的装填因子α≤l,实用中取α为0.5到0.9之间的某个值为宜。

  ②二次探查法(quadratic probing)

  二次探查法的探查序列是:

  hi=(h(key)+i*i)%m 0≤i≤m-1 //即di=i2

  即探查序列为d=h(key),d+12,d+22,…,等。

  该方法的缺陷是不易探查到整个散列空间。

  ③双重散列法(double hashing)

  该方法是开放定址法中最好的方法之一,它的探查序列是:

  hi=(h(key)+i*h1(key))%m 0≤i≤m-1 //即di=i*h1(key)

  即探查序列为:

  d=h(key),(d+h1(key))%m,(d+2h1(key))%m,…,等。

  该方法使用了两个散列函数h(key)和h1(key),故也称为双散列函数探查法。

 

完全散列

如果一种散列技术在进行查找时,其最坏情况内存访问次数为O(1),则称其为完全散列,下图是完全散列的实现方式

 

参考资料: 百度百科,《算法导论》

posted on 2012-09-18 02:32  ZimZz  阅读(320)  评论(0编辑  收藏  举报