散列表(哈希表)
根据关键码值(Key value)而直接进行访问的数据结构。根据给定的关键字来计算出关键字在表中的地址,以加快查找的速度。
常见算法
- 直接定址法
- 取关键字或关键字的某个线性函数值为散列地址。
- 即 f(key) = key 或 f(key) = a*key + b,其中a和b为常数。
- 除留余数法
- 取关键字被某个不大于散列表长度 m 的数 p 求余,得到的作为散列地址。
- 即 f(key) = key % p, p < m。这是最为常见的一种哈希算法。
- 数字分析法
- 当关键字的位数大于地址的位数,对关键字的各位分布进行分析,选出分布均匀的任意几位作为散列地址。
- 仅适用于所有关键字都已知的情况下,根据实际应用确定要选取的部分,尽量避免发生冲突。
- 平方取中法
- 先计算出关键字值的平方,然后取平方值中间几位作为散列地址。
- 随机分布的关键字,得到的散列地址也是随机分布的。
- 随机数法
- 选择一个随机函数,把关键字的随机函数值作为它的哈希值。
- 通常当关键字的长度不等时用这种方法。
哈希冲突
当关键字集合很大时,关键字值不同的元素可能会映像到哈希表的同一地址上,即a!=b,但f(a)=f(b),这种现象称为hash冲突,实际中冲突是不可避免的,只能通过改进哈希函数的性能来减少冲突。
解决冲突
fi=(f(key)+di) % m,0 ≤ i ≤ m-1
- 开放定址法
- 线性探查法(产生堆积问题)
探查时从地址 d 开始,首先探查 T[d],然后依次探查 T[d+1],…,直到 T[m-1],此后又循环到 T[0],T[1],…,直到探查到有空余的地址或者到 T[d-1]为止。
- 平方(二次)探查法(不能探查到哈希表上所有的地址,但至少能探查到一半的地址)
探查时从地址 d 开始,首先探查 T[d],然后依次探查 T[d+di],di 为增量序列1^2, - 12,22,-2^2,……, q^2, -q^2 且q≤1/2 (m-1) ,直到探查到 有空余地址或者到 T[d-1]为止。
- 链地址法
- 把所有的同义词用单链表连接起来