哈希表(一):解决hash冲突的几种方法

(一)线性探测法

线性探测法是最简单的处理冲突的方法。

(1)插入元素:插入元素时,如果发生冲突,算法将从该槽位向后遍历哈希表,直到找到表中的下一个空槽,并将该值放入到空槽当中。

(2)查找元素:查找元素时,首先散列值所指向的槽,如果没有找到匹配,则继续从该槽向后遍历哈希表,直到:1)找到相应的元素;2)找到一个空槽(指示查找的元素不存在);3)整个哈希表都遍历完毕(指示该元素不存在并且哈希表已满)

线性探测法存在的缺点:

(1)处理溢出需要另编程序。一般可以设立一个溢出表,用来存放上述哈希表中放不下的记录。此溢出表最简单的结构是顺序表,查找方法可用顺序查找;

(2)删除工作很复杂。因为一旦对某一个元素删除后,该位置出现空槽,后续查找到该空槽时会认为该元素不存在。需要一种方法对删除元素进行标记;

(3)由于每次都是线性递增,容易导致堆聚,即存入哈希表的记录在表中都连成一片,后续发生冲突的可能性会越大。

(二)二次探测法

本质和线性探测法较类似,只不过线性探测法按照1,2,3,4……的步长进行探测,二次探测法按照1,4,9,16……即平方的方式进行探测。

89: 89 % 10 = 9

18:18 % 10 = 8

49:49 % 10 = 9,递增1,循环走到0位置

58:58 % 10 = 8,递增1,递增4(从8的位置算),循环走到2;

9:9 % 10 = 9,递增1,递增4(从9的位置算),循环走到3。

(三)链地址法

也成为拉链法。其基本思路为:将所有具有相同哈希地址的而不同关键字的元素连接到同一个单链表中。如果选定的哈希表长度为m,则可以将哈希表定义为一个有m个头指针组成的指针数组。凡是给定哈希地址为i的元素,均以节点的形式插入到下标为i的头指针单链表中。并且最新的元素插入到链表的前端,这不仅因为方便,还因为一个经常发生的事实是:最新插入的元素最有可能不久又被访问。

实例图:

对于冲突的哈希值,将其链入到该地址所对应的链表头中。

链地址法的特点:

(1)冲突处理简单,并且没有堆积现象;

(2)由于链地址法各个链表上的结点空间时动态申请的,所以比较适合于造表前没有确定表长的情况;

(3)删除结点的操作比较容易实现,直接对链表中的结点删除即可。

原文地址:https://www.cnblogs.com/scu-cjx/p/8604384.html