算法导论学习笔记-第十一章-散列表

第十一章 散列表

 

总结:这一章讲了直接寻址表和散列表,并介绍了一些散列函数等。

 

1.    直接寻址表

直接将关键字作为数组下标。复杂度O(1)

 

2.    散列表

k->h(k)

降低了空间开销,会产生碰撞,解决碰撞的简单方法是链接法。

对链接法散列,平均情况下,复杂度也是O(1)

 

3.    散列函数

1)  除法散列法

h(k)=k mod mm最好选取与2的整数幂不太接近的质数

2)  乘法散列法

h(k)=[m(kA mod 1)], A为一个常数(0

乘法方法的优点是对m的选择没有什么特别的要求,一般选择它为2的某个幂次。

3)  全域散列

随机的选择散列函数
从一组散列函数中随机地选择一个散列函数,当
(k!=l)时,两者发生碰撞的概率不大于1/m,这样的函数组称为全域的。

 

4.    开放寻址法

开放寻址法指所有的元素都存放在散列表里。

在开放寻址法里,当要插入一个元素时,可以连续地检查散列表的各项,直到遇到一个空槽存放待插入的关键字。对每一个关键字k,探查序列必须是<0,1,..,m-1>的一个排列。

 

伪代码

HASH­-INSERT(T,k)

i <- 0

repeat j <- h(k,i)

      if T[j] = NIL

           then T[j] <- k

                 return j

           else i <- i+1

  until i=m

error “hash table overflow”

 

伪代码

HASH­-SEARCH(T,k)

i <- 0

repeat j <- h(k,i)

      if T[j] = k

           then return j

      i <- i+1

  until i =m or T[j]=NIL

return NIL

 

1)  线性探查

h(k,i)=(h’(k)+i) mod m, i=0,1,…,m-1

初始探查位置确定了整个序列,只有m种不同的探查序列。

存在问题,一次群集,即随着时间的推移,连续被占用的槽不断增加,平均查找时间也随着不断增加。

2)  二次探查

h(k,i)=(h’(k)+a*i+b*i^2) mod m

初始探查位置确定了整个序列,只有m种不同的探查序列。

存在问题,程度较轻的群集现象,二次群集

3)  双重散列

h(k,i)=(h1(k)+i*h2(k)) mod m

为能查找整个散列表,h2(k)要与表的大小m互质。

用了O(m^2)种探查序列

 

5.    完全散列

一种两级的散列方案

每一级上都采用全域散列。

第一级将n个关键字散列到m个槽中,每个槽j中有一个较小的二次散列表Sj。通过仔细的选择第二级散列函数,可以确保在第二级上不出现碰撞。

期望使用的总体存储空间为O(n)

你可能感兴趣的:(算法学习)