开放寻址法
2015-08-02 15:55
169 查看
开始之前先引用一个牛人对开放寻址法的介绍,/article/7761921.html。在此基础上,本文进行更为准确更为恶心地补充说明。在进行坑位选择时,顾客对所有的坑位有一个喜好排序,然后按照特定排序方法,尽量选择最喜欢的坑位,检查里面是否有人,然后进行蹲坑,这就是进行insert操作。而search,可以认为是有人来厕所找人,他知道被找人的喜好,然后按照被找人的喜好,依次查找,如果找到某个人,可以返回位置信息。如果按顺序找到一个“干净”的坑位,就之间返回要找的人没在厕所。“干净”的坑位可以理解是没有人使用过该坑位。假设上厕所的人都不冲厕所,即如果有人用过某坑,会有一个标记,该坑没有记录使用者的信息,只标记被使用过了,而且现在没人,即这编码被insert过,而且又delete掉了。尽管坑可能被用过,但是只要按照喜好顺序,只要发现没人,顾客就会选择这个坑位,被insert到这个位置。而找人时,发现脏的没人的坑位,需要继续寻找,因为可能被找的人已经离开厕所了,也可能之前有人,被找的人在下一个位置,因此直到找到“干净”的坑位,确定,目前厕所里面没有要找的人。
坑位编号是0,1,……m-1,但是喜好编号是另一个顺序h(k,0),h(k,1),……h(k,m-1),两个集合是一一映射,但是不是按顺序对应的。常用的对应算法有一下几种。
线性探查
h(k,i)=(h′(k)+i)modm(h^{'}(k)+i) \mod{m}。该算法相当于,通过某种映射首先选择某个最喜欢的坑位,然后依次选择下一个坑位,到了m-1,再回到初始0号坑位,一共有m种不同的喜好顺序。
凭我们的历史经验可知道,当这个坑被选择时,相邻的坑位被选择几率会很大,《算法导论》中说某坑位前有i个位置都被占了,则该位置为下一个被占用的概率是(i+1)/m,没有想清楚为什么。于是乎有了下面
二次探查
h(k,i)=(h′(k)+c1i+c2i2)modm(h^{'}(k)+c_{1}i+c_{2}i^{2}) \mod{m},也是存在m中不同的喜好序列。
双重散列
h(k,i)=(h1(k)+ih2(k))modm(h_{1}(k)+ih_{2}(k)) \mod{m},该算法有m2m^{2}中探查序列,因为h1(k)modmh_{1}(k)\mod{m} 结果指向某一个特定的初始位置,有m种可能,而h2(k)modmh_{2}(k) \mod{m}又指向m种特定偏移的一种。为了查找整个散列表,要求所有的h2(k)h_{2}(k)和m互质。因为如果h2(k)h_{2}(k)和m的最大公约数是d,h2(k)modmh_{2}(k) \mod m和m的最大公约数也是d(辗转相除算法的由来),则t∈[0,m−1]t \in [0,m-1],t∗h2(k)modmt*h_{2}(k) \mod m可以整除d,因此,该双重散列只能遍历散列表中1/d个元素,因此当d=1时,即h2(k)h_{2}(k)和m互质,则可以遍历整个散列表。
坑位编号是0,1,……m-1,但是喜好编号是另一个顺序h(k,0),h(k,1),……h(k,m-1),两个集合是一一映射,但是不是按顺序对应的。常用的对应算法有一下几种。
线性探查
h(k,i)=(h′(k)+i)modm(h^{'}(k)+i) \mod{m}。该算法相当于,通过某种映射首先选择某个最喜欢的坑位,然后依次选择下一个坑位,到了m-1,再回到初始0号坑位,一共有m种不同的喜好顺序。
凭我们的历史经验可知道,当这个坑被选择时,相邻的坑位被选择几率会很大,《算法导论》中说某坑位前有i个位置都被占了,则该位置为下一个被占用的概率是(i+1)/m,没有想清楚为什么。于是乎有了下面
二次探查
h(k,i)=(h′(k)+c1i+c2i2)modm(h^{'}(k)+c_{1}i+c_{2}i^{2}) \mod{m},也是存在m中不同的喜好序列。
双重散列
h(k,i)=(h1(k)+ih2(k))modm(h_{1}(k)+ih_{2}(k)) \mod{m},该算法有m2m^{2}中探查序列,因为h1(k)modmh_{1}(k)\mod{m} 结果指向某一个特定的初始位置,有m种可能,而h2(k)modmh_{2}(k) \mod{m}又指向m种特定偏移的一种。为了查找整个散列表,要求所有的h2(k)h_{2}(k)和m互质。因为如果h2(k)h_{2}(k)和m的最大公约数是d,h2(k)modmh_{2}(k) \mod m和m的最大公约数也是d(辗转相除算法的由来),则t∈[0,m−1]t \in [0,m-1],t∗h2(k)modmt*h_{2}(k) \mod m可以整除d,因此,该双重散列只能遍历散列表中1/d个元素,因此当d=1时,即h2(k)h_{2}(k)和m互质,则可以遍历整个散列表。
相关文章推荐
- Java学习笔记(2015.7.27~7.31)
- uva 12300
- [深入理解Android卷一全文-第五章]深入理解常见类
- POJ 1862 Stripies(优先队列)
- Android UI 关于Android计量单位dip dp sp px 你所需要知道的一切
- Git
- [python]解析python打印出来的数组
- iOS基础-UIKit框架-手势处理
- hdu5341 Gcd and Lcm
- hdu 5323
- man文档阅读技巧
- iOS学习笔记4-GCDAsyncUdpSocket的使用(实现异步发送接收数据)
- [深入理解Android卷一全文-第五章]深入理解常见类
- 设计模式六大原则
- Outputting Strings in the Console
- 102.Binary Tree Level Order Traversal
- 浅谈android入门
- apt-get的软件源配置
- 双向链表的插入删除操
- 解决ScrollView嵌套ListView和GridView冲突的方法