当前课程知识点:数据结构(下) > 第九章 词典 > (d2)散列:排解冲突(2) > 09D2-5 双蜓点水
如果需要进一步的提高装填因子
不妨可以考虑将常规的平方试探扩展为所谓的双向平方试探
具体来说 一旦发生冲突
则交替的向前向后以递增的平方数为间隔逐一的试探
整个试探过程 以及对应的试探链
可以由这幅图来表示
假设最初的散列映射位置在这
接下来如果从这个位置开始 持续的发生冲突
那么第一个试探的位置应该是这
如果依然冲突 那么下一个试探的位置应该是这里
第三次试探的位置 在这里
第四次在这儿 依此类推
如果将双向试探的位置罗列出来 大致应该是这样
从居中的0号单元开始 向后转入相对而言的1号桶
再转向-1号桶 再转向+4号桶 再转向-4号桶
以及+9号桶 -9号桶 依此类推
当然具体的桶单元编号还需对M取模
对于此前那个长度为11的散列表而言
这种方法非常有效
因为如果像这样将各次试探的位置具体列出来
我们就会发现
前11次试探的位置不多不少恰好覆盖了0到10这11个桶
也就是说 只要装填因子还没有达到100% 仍有空桶
那么按照这种方式进行试探 就一定能找到一个空桶
你也不难发现 对于其他的一些素数表长也有这种好现象
比如考察长度为7的散列表
可以看到 如果也是采用双向平方探测
那么前7次试探的位置 也恰好覆盖了0到6这7个单元
尽管已经看到了 这样的两个好的实例
我们还是有理由怀疑其中存在着运气的成分
我们知道此时的查找链
实际上是由正向和逆向两个子查找链依此交错而构成
在讨论单向平方探测时 我们已经证明
在正向的子查找链中 前M/2上整的位置必然彼此互异
而由对称性 逆向的子查找链
也应该在内部具有这样的性质
那么在这两个子查找链之间 除了公共的起点0
是否还有其他公共的单元呢
如果没有 那么它们的总长 就应该恰好是M
也就是说 它们的并集将完整的覆盖所有的桶
我们刚才已经看到在M=11时 情况的确如此
正向的查找链与逆向查找链之间没有任何公共元素
而M=7时 情况也是如此
然而正如我们刚才所担忧的那样 情况并非总是如此
比如M=13时 我们会在两个子查找链中同时发现4 9 3等等
而在做过进一步的观察之后
你甚至会发现此时的正向子查找链与逆向子查找链
居然是由同样的6个数组成的
我们也不难找的更多这样的反例
最简单的莫如M=5 你会发现
它的正向子查找链与逆向子查找链也是由同样的两个数组成
以下这些实例告诉我们 对于双向平方试探法而言
采用某些素数表长 可以行之有效
而采用另外一些素数的表长 却非常糟糕
那么同样是素数 这两种类型之间 有什么区别呢
我们在相应的设计散列表时 又该如何取舍呢
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)概述
--07A-1 纵览
--07A-5 接口
-(a)概述--作业
-(b1)BST:查找
-第七章 二叉搜索树--(b1)BST:查找
-(b2)BST:插入
-(b2)BST:插入--作业
-(b3)BST:删除
-第七章 二叉搜索树--(b3)BST:删除
-(c)平衡与等价
-(c)平衡与等价--作业
-(d1)AVL树:重平衡
-第七章 二叉搜索树--(d1)AVL树:重平衡
-(d2)AVL树:插入
-(d2)AVL树:插入--作业
-(d3)AVL树:删除
-(d3)AVL树:删除--作业
-(d4)AVL树:(3+4)-重构
-(d4)AVL树:(3+4)-重构--作业
-本章测验
--章节测验
-(a1)伸展树:逐层伸展
--习题
-(a2)伸展树:双层伸展
--习题
-(a3)伸展树:算法实现
--习题
-(b1)B-树:动机
--习题
-(b2)B-树:结构
--习题
-(b3)B-树:查找
--习题
-(b4)B-树: 插入
--习题
-(b5)B-树: 删除
--习题
-(xa1)红黑树:动机
--习题
-(xa2)红黑树:结构
--习题
-(xa3)红黑树:插入
--习题
-(xa4)红黑树:删除
-本章测验
--习题
-(b)散列:原理
--09B-3 数组
--09B-4 原理
--09B-5 散列
--09B-6 冲突
--习题
-(c)散列:散列函数
--习题
-(d1)散列:排解冲突(1)
--习题
-(d2)散列:排解冲突(2)
--习题
-(e)桶/计数排序
--习题
-本章测验
--本章测试
-(a1)需求与动机
--习题
-(a2)基本实现
--习题
-(b1)完全二叉堆:结构
--习题
-(b2)完全二叉堆:插入与上滤
--习题
-(b3)完全二叉堆:删除与下滤
--习题
-(b4)完全二叉堆:批量建堆
--习题
-(c)堆排序
--习题
-(xa1)左式堆:结构
--习题
-(xa2)左式堆:合并
--习题
-(xa3)左式堆:插入与删除
-本章测验
--本章测试
-(a)ADT
--习题
-(b1)串匹配
--习题
-(b2)蛮力匹配
--习题
-(c1)KMP算法:从记忆力到预知力
--习题
-(c2)KMP算法:查询表
--习题
-(c3)KMP算法:理解next[]表
--习题
-(c4)KMP算法:构造next[]表
--习题
-(c5)KMP算法:分摊分析
--习题
-(c6)KMP算法:再改进
-(d1)BM_BC算法:以终为始
-(d2)BM_BC算法:坏字符
-(d3)BM_BC算法:构造bc[]
-(d4)BM_BC算法:性能分析
-(e1)BM_GS算法:好后缀
-(e2)BM_GS算法:构造gs表
-(e3)BM_GS算法:综合性能
-(f1)Karp-Rabin算法:串即是数
-(f2)Karp-Rabin算法:散列
-本章测验
--本章测试
-(a1)快速排序:算法A
-- 12a1-5: 实例
--习题
-(a2)快速排序:性能分析
--习题
-(a4)快速排序:变种
-(b1)选取:众数
-(b3)选取:通用算法
--习题
-(c1) 希尔排序:Shell序列
--习题
-(c2)希尔排序:逆序对
-本章测验
--本章测试