目录
一. 散列表的基本概念
二. 散列表的冲突问题
三. 构造散列函数
四. 处理冲突
一. 散列表的基本概念
散列表简而言之就是一个根据一个对应关系(这个对应关系也叫散列函数)来存储关键码(关键字)的一个表。
例如,当散列函数为H(key)=key时,那么就相当于9号这个位置存储的关键码就是9。
二. 散列表的冲突问题
当散列函数不一样时,可能会导致不同的关键字会存放到同一个散列地址,这就叫做冲突。
如下所示:
所以我们要想使用散列表就得解决好两个问题,一个就是构造一个好的散列函数,所选函数尽可能简单,以便提高转换速度。另外一个就是制定一个好的解决冲突的方案。
三. 构造散列函数
构造散列函数需要考虑的因素:
1)执行速度(即计算散列函数所需时间)
2)关键字的长度
3)散列表的大小
4)关键字的分布情况
5)查找频率
下面我们学习两种用的最多的散列函数,一种是直接定址法,另外一种则就是除留余数法。
直接定址法:
除留余数法:
四. 处理冲突
处理冲突的最常用方法主要有两大类:开放定址法和链地址法。
其中开放定址法又包括三种,分别是线性探测法,二次探测法和伪随机探测法。
开放定址法的基本思想就是有冲突时就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将数据存入。
如下所示:
也就是说,要是当前散列地址非空,那么线性探测法就是每次往后移动一个位置去寻找一个空位置;而二次探测法则每次往后移动1的平方,-1的平方等等的二次序列。伪随机探测法则就是每次移动的位置随机。
链地址法建立散列表的步骤如下所示:
1)取数据元素的关键字key,计算其散列函数值(地址)。若该地址对应的链表为空,则将该元素插入此链表中;否则执行第二步来解决冲突。
2)根据选择的冲突处理方法,计算关键字key的下一个存储地址,若该地址对应的链表不为空,则利用链表的前插法或后插法将该元素插入此链表中。
链地址法的优点:
1)非同义词不会冲突,无“聚集”现象。
2)链表上结点空间动态申请,更适合于表长不确定的情况。
最后总结:
1)散列表优于一些传统的查找技术。
2)链地址法优于开地址法。
3)除留余数法作散列函数优于其它类型函数。