哈希表相关概念

参考:
https://www.cnblogs.com/songdechiu/p/6954038.html
https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/算法 - 符号表.md

1. 第一步是用哈希函数将键转换为数组的一个索引,理想情况下不同的键都能转换为不同的索引值,但是实际上会有多个键哈希到到相同索引值上。

因此,第二步就是处理碰撞冲突的过程。这里有两种处理碰撞冲突的方法:separate chaining(拉链法)和linear probing(线性探测法)

哈希表是算法在时间和空间上做出权衡的经典例子。

如果没有内存限制,算法可以直接将键作为数组(可能是超级大)的索引,那么所有的查找操作只需要访问一次内存即可完成。但这种理想情况一般不会出现,因为当键很多时,需要的内存太大。

如果没有时间限制,算法可以使用无序数组并进行顺序查找,这样只需要很少的内存。

哈希表使用了适度的空间和时间并在这两种极端之间找到了一种平衡。

一个优秀的哈希方法需要满足三个条件:

一致性——等价的键必须产生相等的哈希值

高效性——计算简便

均匀性——均匀地哈希所有键

假设

假设:算法使用的哈希函数能够将所有键均匀并独立地分布到0和M-1之间。

这个假设是实际上无法达到的理想模型,但是是算法实现哈希函数的指导思想。

三、基于拉链法的哈希表

1、简介
哈希函数将键转化为数组索引,第二步就是需要进行碰撞处理。

一种最直接的方法是将大小为M的数组的每个元素指向一条链表,链表的每个节点都储存了哈希值为该位置数组下标的键值对。

这种方法称为拉链法(separate chaining)。因为冲突的元素都放在同一个链表上。
这种方法的思想就是:选择足够大的M使得链表都尽可能短以保证高效查找。

查找顺序:先根据哈希值找到相应的链表,然后遍历链表查找相应的键。

四、基于线性探测法的哈希表

1、简介
实现哈希表的另一种方法是用大小为M的数组保存N个键值对,其中M>N。这种方法依靠数组中的空位解决碰撞冲突。

当发生碰撞时,算法检查下一个位置(将索引加1)。

这样线性探测可能会产生三种结果:

命中,该位置的键和要查找的键相同。

未命中,该键为空。
继续查找,该位置的键和要查找的键不相同。


和拉链法一样,线性探测法哈希表的性能也依赖于N/M的比值。

只不过意义不一样,这里是N/M是哈希表中被占用的空间比例,算法使用动态调整数组大小方法来保证使用率在1/8到1/2之间。

和拉链法一样,动态调整数组大小需要重新哈希所有键。

详细代码实现请见 连接。

发布了39 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/poppyl917/article/details/89408208
今日推荐