:本文如涉及到代码,均经过Python 3.7实际运行检验,保证其严谨性。

本文阅读时间约为6分钟

前面说过,如果两个数据项被散列映射到同一个槽,需要一个系统化的方法在散列表中保存第二个数据项,这个过程被称为“解决冲突”。

如果散列函数是完美的,那就不会有散列冲突,但实际情况是,完美散列函数常常并不存在,解决散列冲突成为散列方法中很重要的一部分。

解决散列的一种方法就是,为冲突的数据项再找一个开放的空槽来保存。最简单的就是从冲突的槽开始往后扫描,直到碰到一个空槽。如果到散列表尾部还未找到,则从首部接着扫描。

这种寻找空槽的技术被称为“开放定址(open addressing)”。

向后逐个槽寻找的方法则是开放定址技术中的“线性探测(linear probing)”。

线性探测Linear Probing

还是以前面说过的这一组数据来作为示例说明线性探测具体如何操作。 假设有下列数据项:

54, 26, 93, 17, 77, 31

通过求余法我们得到了其散列值及对应槽号如下图Pic-512-1的上半部分所示。

Pic-512-1 线性探测示例

现在,我们要做的是,把44、55、20三个数据项逐个插入到该散列表中。具体过程如下:

h(44)=0,但发现0#槽已被77占据,向后(向右)找到第一个空槽#1,把44保存在1#槽中。

h(55)=0,因为0#槽、1#槽均已被占据,后面的2#槽是空的,因此把55保存在2#槽中。

h(20)=9,发现9#槽已被31占据,向右,10#也被54占据,再从头扫描,0#、1#、2#等槽均已被占据,后面的3#槽是空的,因此把20保存在3#槽中。

整个过程如上图Pic-512-1所示。

需要注意的是,如果采用线性探测方法来解决散列冲突的话,那么散列表的查找也应该遵循同样的规则。

如果在散列位置没有找到查找项的话,就必须向后做顺序查找,直到找到查找项或者碰到空槽(即查找失败)。

线性探测的改进

线性探测法有一个缺点,就是有聚集的趋势,即:如果同一个槽冲突的数据项较多的话,这些数据项就会在槽附近聚集起来,从而连锁式影响其他数据项的插入。

为了避免这种不利的聚集趋势,一种方法就是将线性探测扩展,从逐个探测改为跳跃式探测。比如,以+3的方式探测插入44、55、20。

还是用线性探测的例子来说明跳跃式探测是具体如何操作的。

还是假设有下列数据项:

54, 26, 93, 17, 77, 31

我们现在要把44、55、20三个数据项跳跃式(指定以+3的间隔)插入到该散列表中。具体过程如下:

h(44)=0,但发现0#槽已被77占据,向后+3个槽,找到#3槽。#3槽是空槽,可以存放数据,于是把44保存在3#槽中。

h(55)=0,因为0#槽,向后+3个槽,找到#3槽,已有数据项44;继续向后+3个槽,找到#6槽,已有数据项17在里面;继续向后+3个槽,找到#9槽,依然有数据项31占据着;继续向右+3个槽,到了#1槽。#1槽为空,可以存放数据项,于是把55保存在#1槽中。

h(20)=9,发现9#槽已被31占据,向右+3个槽,找到1#槽,不为空;继续向右+3个槽,找到#4,有26在里面;继续向右+3个槽,#7槽为空,可以存放数据项,于是把20存放到#7槽中。

如下图Pic-512-2所示:

Pic-512-2 跳跃式探测示例

冲突解决方案:再散列rehashing

重新寻找空槽的过程可以用一个更为通用的“再散列rehashing”来概括:

newhashvalue = rehash(oldhashvalue)

对于线性探测来说,

rehash(pos) = (pos + 1) % sizeoftable

对于“+3”的跳跃式探测则是:

rehash(pos) = (pos + 3) % sizeoftable

跳跃式探测的再散列通式是:

rehash(pos) = (pos + skip) % sizeoftable

这里要注意的是,skip的取值不能被散列表大小整除,否则会产生周期,造成很多空槽永远无法探测到的后果。如果把散列表的大小设为质数(如11),则可以避免这种情况。

除了将线性探测改善为跳跃式探测,还能将其变为“二次探测(quadratic probing)”。

二次探测是什么意思呢?就是对于

rehash(pos) = (pos + skip) % sizeoftable

来说,skip的值不再是固定的某个值,而是逐步增加的,如1、3、5、7、9等。 这样槽号就会是原散列值以平方数增加:

h, h+1, h+4, h+9, h+16...

这也是一种能令散列值分散的好办法。

冲突解决方案:数据项链Chaining

除了寻找空槽的开放定址技术之外,另一种解决散列冲突的方案是,将容纳单个数据项的槽扩展为容纳数据项集合(或者对数据项链表的引用)。

这样,散列表中的每个槽就可以容纳多个数据项,如果有散列冲突发生,只需要简单地将数据项添加到数据项集合中。

查找数据项时则需要查找同一个槽中的整个集合。在同一个集合中查找,就用顺序查找法。当然,随着散列冲突的增加,对数据项的查找时间也会相应增加。

还是拿那组数据为例:

54, 26, 93, 17, 77, 31

要求插入44、55、20三个数据项。

如用数据项链的方法,每个槽都可以容纳一个数据项的集合。操作示意如下图Pic-512-3所示:

Pic-512-3 数据项链示例

To be continued.

散列表查找失败平均查找长度_Python数据结构与算法56:排序与查找:冲突解决方案...相关推荐

  1. python列表是顺序表还是链表_Python数据结构与算法(链表使用详解)

    链表 单向链表 p是头节点,指向第一个值,最后一个是伪节点,因为不指向地址. 表元素域elem用来存放具体的数据 链接域next用来存放下一个节点的位置(python中的标识) 变量p指向链表的头节点 ...

  2. 散列表查找失败平均查找长度

    如果你看了很多其他博客然后都看不懂看到了这篇,你一定可以容易懂的!我佛了,这么简单的东西死板地讲题目不讲原理鬼看得懂啊,这种风气真的不行,我忍不住想骂一声垃圾,啥玩意儿,误人子弟!原理懂了啥题不会做? ...

  3. 折半查找判定树 二叉排序树 查找成功平均查找长度 查找失败平均查找长度

    写在前边的话:你的支持是我写作的动力,有帮助到你的话麻烦点赞加收藏呦.感激不尽!如有错误也请留言指正. 考研数据结构练习,欢迎订阅我的专辑<考研数据结构题型分类讲解练习> [哈尔滨工业大学 ...

  4. 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

  5. 数据结构和算法系列13 五大查找之哈希查找

    原文地址 http://www.cnblogs.com/mcgrady/p/3294871.html 数据结构和算法系列13 五大查找之哈希查找 这一篇要总结的是五天查找的最后一篇,哈希查找,也称为散 ...

  6. 【数据结构与算法】比较法分析查找算法与查找结构

    基本的查找技术: 线性表的查找技术 顺序查找 分块查找 二分查找(折半查找) 插值查找 树表的查找技术 二叉排序树 平衡二叉树 B树(B+树.B-树等) 散列表的查找技术 开散列表 闭散列表 顺序查找 ...

  7. 无序链表(顺序查找)和有序数组(二分查找)-基础实现-符号表(二)-数据结构和算法(Java)

    文章目录 1 无序链表的顺序查找 1.1 无序链表实现 1.2 分析 2 有序数组中的二分查找 2.1 实现 2.2 分析 3 对二分查找的分析 4 总结 5 后记 1 无序链表的顺序查找 1.1 无 ...

  8. 数据结构与算法--线性表的查找

    一.查找的基本概念 1) 查找表: 查找表是由同一类型的数据元素(或记录)构成的集合         2) 由于集合中的数据元素之间存在着松散的关系,因此查找表是一种应用灵便的结构 3) 查找: 根据 ...

  9. Python基础算法:排序、查找、二叉树

    文章目录 排序算法 1.插入排序 2.交换排序 3.冒泡排序 4.归并排序 4.1.合并两个有序序列 4.2.完整版 查找算法 1.顺序查找 2.二分查找 3.字符串查找 完全二叉树 1.创建树节点[ ...

最新文章

  1. 支持向量机ModuleNotFoundError: No module named ‘sklearn.datasets.samples_generator‘
  2. html中div不在火狐居中,Firefox嵌套CSS中div标签居中问题解决方法
  3. Asp.net序中常用代码汇总(五)
  4. 10位IT领袖给应届毕业生的10条忠告
  5. Linux - which xxx - 查找执行的命令所在的路径
  6. 初二物理模型有哪些_暑假新初二、新初三的数学该怎么学,教辅怎么买,题该怎么刷?看这里~...
  7. 创建自定义Tabs组件-01
  8. js提取正则中的字符串
  9. 关于Request.ServerVariables(HTTP_REFERER)
  10. (10)Verilog HDL异步复位同步释放
  11. 详解REST架构风格
  12. 民生证券手机网上开户流程
  13. JavaFX之Scene Builder详细使用说明之设置篇(2)——属性Properties
  14. 读书笔记:《你拿什么定义自己》
  15. html p 会自动换行,css如何设置p标签不换行?
  16. uva 10041 - Vito's Family
  17. 使用Photoshop给Premiere批量添加对白字幕听语音 |浏览:25974|更新:2013-12-23 23:18|标签:photoshop premiere 使用Photoshop给Pre
  18. windows 7 浏览器无法进网站,提示安全证书存在问题(GlobalSign)
  19. 单片机控制ws2812b
  20. 什么是IDC?数据中心该如何选择?

热门文章

  1. mysql 主主复制的配置流程
  2. EasyNVR内网摄像机接入网关+EasyNVS云端管理平台,组件起一套轻量级类似于企业级萤石云的解决方案...
  3. Process和ProcessBuilder入门【原】
  4. C#最简单最完整的webservice实例
  5. ARM-Button-Driver-硬件图
  6. Windows下的ssh姐妹花 Xshell 和 Xftp
  7. vue --- 2.0响应式补充
  8. flutter --- 使用dio包
  9. View的绘制-layout流程详解
  10. Atlassian发布事故管理解决方案Jira Ops