哈希表(散列表)——一种面向查找的存储结构

避免key的繁琐比较,是种高效的查找数据结构,记录之间无关联

 

 

  • 哈希函数/散列函数

    存储位置=f(关键字)

   不需遍历或比较,直接找到存储位置。

   存取使用同一个散列函数:存储时,通过散列函数计算记录的散列地址,存储记录;查找时,通过散列函数计算记录的散列地址,查找记录

  • 散列函数的评判

(1)计算简单,时间短(2)散列地址分布均匀,可以有效利用存储空间,减少冲突

(3)雪崩效应key的微小变化可以使f(key)发生很大的变化

 

  • 哈希表/散列表

    采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间被称为哈希表。

 

  • 几类散列函数

(1)直接定址法

取关键字的线性函数值f(key)=a*key+b

优点:简单,均匀,不冲突

缺点:需要知道关键字的分布情况

适用范围:查找表小且连续的情况

(2)数字分析法

抽取key的一部分,再用反转、左移、右移、叠加进行辅助

适用范围:关键字位数比较大,关键字若干位分布较均匀

(3)平方取中法

对key的平方值取中间几位作为散列地址

适用范围:不知道关键字分布,位数不是很大

(4)折叠法

对key分成几段求和,再取末尾几位

(5)除留余数法

f(key)=key mod p(p<=m) 散列表表长为m

根据经验,为减少冲突,p为小于或等于表长m(最好接近m)的最小质数或不包含小于20质因数的合数。

(6)随机数法

f(key)=random(key)   random为伪随机函数

适用范围:关键字的长度不等

 

  • 冲突

key1!=key2,却有f(key1)=f(key2),将key1和key2称为散列函数的同义词

 

  • 处理冲突的方法

(1)开放定址法

发生冲突就找下一个空的散列地址

线性探测法:      fi(key)=(f(key)+di)mod m            di=1,2,。。。m-1

堆积现象:不是同义词却需要争夺同一个地址,比如说因为冲突所以需要把地址不断往后挪,往后挪的时候就会发生堆积

二次探测法:     fi(key)=(f(key)+di)mod m            di=1^2,-1^2,2^2,-2^2,...q^2,-q^2    q<=m/2

                     可以双向寻找空位置,使用平方可以使关键字不都聚集在某一块区域

随机探测法:  对位移量di使用随机函数(这里指伪随机)取得

(2)再散列函数法

准备多个散列函数

   fi(key)RHi(key)     i=1,2,...,k         RHi指不同的散列函数

优点:关键字不聚集

缺点:计算时间大

(3)链地址法/拉链法

将关键词为同义词的记录存储在一个单链表中,有冲突就增加节点,保证解决冲突但引入了遍历单链表的损耗。

哈希表(散列表)——一种面向查找的存储结构_第1张图片

(4)公共溢出区法

  分成基本表和溢出表,将冲突的关键字存储到溢出表中。

查找时,如果相应位置的值不相等,就到溢出表中进行顺序查找

适用范围:冲突数据很少

 

  • 散列表查找性能相关因素

散列函数是否均匀

处理冲突的方式:比如链地址法 优于 二次探测法 优于 线性探测法

散列表的填装因子=填入表中记录个数/散列表长度   一般是浪费一点空间,使平均长度限定在一个范围内

 

参考文献:

《大话数据结构》

 

你可能感兴趣的:(数据结构)