数据结构与算法:哈希表基本原理及Python实现
哈希表的基本原理
1. 哈希表与哈希函数
哈希表与二叉树、链表等数据结构类似,也是用于存放数据的一种数据结构。哈希表的具体应用场景为:快速判断一个数据是否存在于该数据结构中,且找到其下标(比如:判断22是否在1、65、34、97、12、22、48、89中)。
哈希表通过哈希函数实现,哈希函数实际上就是一个取模(求余数)的过程,我们直接以例子来讲解哈希表:
需要存放15、23、4、19四个数据(称为关键字Key),数组大小设置为7,那么下标范围就是0~6,将关键字分别对17求模,并将关键字放在对应的下标处即可,如图所示。
2. 哈希表冲突解决方法
如果求模的结果相同产生冲突,一般有2种解决方法:链表解决和开放地址解决。
2.1 链表解决
顾名思义,在对应下标的关键字中引入链表,引入next指针将产生冲突的关键字用链表数据结构存储。
2.2 开放地址解决
开放地址解决,也就是说将哈希表中其他有空关键字位置的下标用来存放冲突的关键字。开放地址解决一般有3种方式:
2.2.1 线性探测法
如果遇到冲突,新下标 = 原下标 + i i i( i i i表示第 i i i次重复),如果新下标也有关键字了,i = i + 1,继续往后寻找即可。
实际上也就是逐一往后寻找有空位的下标。
2.2.2 平方探测法
如果遇到冲突,新下标 = 原下标 + i 2 i^2 i2( i i i表示第 i i i次重复)
平方探测法可以使得关键字的分布不会过于密集。
2.2.3 双哈希法
如果遇到冲突,新下标 = 原下标 + i ∗ h a s h 2 i*hash2 i∗hash2(关键字)
其中, h a s h 2 hash2 hash2(关键字) = R - (关键字对R取模),R需要小于原数组的大小。比如:需要将18、35放入数组大小为17的哈希表中。首先放入18,18对17取模为1,所以放在下标为1的位置。同理,35对17取模为1,也应该放在下标为1的位置,于是发生冲突。取R为7,35对7取模结果为0,所以 h a s h 2 hash2 hash2 = 7 - 0 = 7,于是新下标 = 原下标 + 1 ∗ 7 1*7 1∗7。
P.S. 不直接 h a s h 2 hash2 hash2(关键字) = (关键字对R取模) 是防止 h a s h 2 hash2 hash2(关键字)=0的特殊情况。
哈希表的Python实现
待补充