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

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

本文阅读时间约为6分钟

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

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

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

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

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

线性探测Linear Probing

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

54, 26, 93, 17, 77, 31

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

a6dcfab848c3e7cfb759c2218540e1c6.png

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所示:

5a2645b2712d7ae2b4b459b6d9cf1ddb.png

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所示:

202d956e7aec3bc500657997ae50c13f.png

Pic-512-3 数据项链示例

To be continued.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259053.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Face Alignment by 3000 FPS系列学习总结(一)

广播: 如今的opencv已经提供了LBF的训练和测试代码,推荐阅读 《使用OpenCV实现人脸关键点检测》 face alignment 流程图 train阶段 测试阶段 预处理 裁剪图片 tr_data loadsamples(imgpathlistfile, 2); 说明: 本函数用于将原始图片取…

macbook 移动硬盘无法写入_如何升级MacBook笔记本的SSD硬盘-菜鸟折腾系列一

2010 年的时候买了 09 年末的 MACBOOK 小白,由于技术发展,软件越来越吃硬件内存,现在2G 内存别提基本的工作了,连开机都有困难,每次一点就一个风火轮,基本就是一块 13 寸的板砖了。。。众所周知 HDD 机械硬…

face alignment by 3000 fps系列学习总结(二)

准备初始数据 mean_shape mean_shape就是训练图片所有ground_truth points的平均值.那么具体怎么做呢?是不是直接将特征点相加求平均值呢? 显然这样做是仓促和不准确的。因为图片之间人脸是各式各样的,收到光照、姿势等各方面的影响。因此…

parasoft Jtest 使用教程:功能配置之查找错误

2019独角兽企业重金招聘Python工程师标准>>> parasoft Jtest介绍和试用>>> 今天开始为大家带来parasoft Jtest功能配置板块教程,也是系列教程中最重要的一部分。 通过运行Jtest的BugDetective和使用最重要的一套规则来进行编码标准静态分析&…

kmp入门小结

void get_next(char *s) {int len strlen(s);int j 0; int k -1;while (j < len){if (k -1 || s[j] s[k]){j; k; next[j] k;}else k next[k];} } 设t next[i]; next[i] 表示的是 i之前最大的t满足 s[0...t-1] s[i-t...i-1] 比如 0123 4 0123 5 &#xff0c;next[…

基于visual Studio2013解决面试题之0807strstr函数

&#xfeff;&#xfeff;&#xfeff;题目解决代码及点评/*写strstr函数简单的遍历去查找吧 */#include <iostream> #include <stdio.h>const char *my_strstr(const char *str, const char *sub_str) {// 遍历for(int i 0; str[i] ! \0; i){int tem i; //tem保…

aop在项目中的实际运用_mypy在实际项目中的应用

我认为静态类型似乎被吹捧过高了。尽管如此&#xff0c;mypy极低的侵入性能带来许多好处。关于如何在现有的Python项目中添加类型&#xff0c;以下是我的一些想法&#xff0c;大致按重要性排序。首先确保mypy成功运行 Mypy上手时两个很常见的问题有&#xff1a;1.Mypy没有作为构…

face alignment by 3000 fps系列学习总结(三)

训练 我们主要以3000fps matlab实现为叙述主体。 总体目标 我们需要为68个特征点的每一个特征点训练5棵随机树&#xff0c;每棵树4层深&#xff0c;即为所谓的随机森林。 开始训练 分配样本 事实上&#xff0c;对于每个特征点&#xff0c;要训练随机森林&#xff0c;我们需…

HDU 2049 不容易系列之(4)——考新郎( 错排 )

链接&#xff1a;传送门思路&#xff1a;错排水题&#xff0c;从N个人中选出M个人进行错排&#xff0c;即 C(n,m)*d[m]补充&#xff1a;组合数C(n,m)能用double计算吗&#xff1f;第二部分有解释 Part 1. 分别求出来组合数的分子和分母然后相除/******************************…

linux服务器选ubantu或centos_如何通过SSH连接阿里云上的Linux系统

首先SSH是啥&#xff0c;维基一下&#xff1a;Secure Shell&#xff08;安全外壳协议&#xff0c;简称SSH&#xff09;是一种加密的网络传输协议&#xff0c;可在不安全的网络中为网络服务提供安全的传输环境[1]。SSH通过在网络中创建安全隧道来实现SSH客户端与服务器之间的连接…

paypal之nodejs 框架 Kraken-js 源码分析

本文是基于 kraken-js 0.6.1 版本的 关于如何使用kraken-js 可以去看看官网的使用文档 点击这里 。kraken-js 是基于express之上的&#xff0c;目的在于让工程师更多的去关注代码逻辑&#xff0c;少关注自身的开发环境&#xff0c;所以他将express所有的一些公用的配置都写在了…

go build 参数_Go语言 通过go bulid -tags 实现编译控制

Go语言提供的build tag 条件编译特性&#xff0c;顾名思义&#xff0c;只有在特定条件下才会构建对应的代码。比如下面的源文件只有在设置debug构建标志时才会被构建&#xff1a;// build debugpackage mainvar buildMode "debug"可以用以下命令构建&#xff1a;go …

selinux 的管理

第十单元selinux 的管理一 显示及更改 SELINUX 模式getenforce ###显示selinux模式setenforce 0|1 ##0指permissive警告&#xff0c;1 表示 enforcing强制###vim /etc/sysconfig/selinux ###修改selinux开机状态###注&#xff1a;disable表示关闭&…

ubuntu15.10下安装opencv2.4.9python上调用opencv库

对于centos&#xff0c;可以参考&#xff1a;Install OpenCV-Python in Fedora 如果IPP难以下载可以在cmake时禁掉它&#xff0c;只需&#xff1a;cmake -DWITH_IPPOFF OpenCV3.3CUDA9.0 安装过程中遇到的问题&#xff0c;解析&#xff1a; https://blog.csdn.net/u014613745/a…

键盘改键软件_一秒五键,一键三招,万种光污染,杜伽K310樱桃轴机械键盘感受...

机械键盘我一直用的青轴&#xff0c;或者各种其他名字但其实本质就是青轴的。喜欢青轴那种清脆的声音&#xff0c;在我听来如同山间小溪流水般的叮咚。不过这声音在夜间分外的具有穿透力&#xff0c;更会在人身体不好的时候难以承受&#xff0c;所以每每用过之后却又不得不换回…

codeigniter钩子的使用

CodeIgniter 的钩子功能&#xff0c;使得我们可以在不修改系统核心文件的基础上&#xff0c;来改变或增加系统的核心运行功能。可是钩子究竟该怎么用呢&#xff1f;虽然不是很难&#xff0c;不过很多刚用ci的朋友可能还是不明白怎么用。 通过本文的简单实例&#xff0c;大家一下…

powerdesigner画关系图_想画好手绘,这些图你一定要画一下!

画好手绘除了对透视要深入了解掌握以及线条运用把握之外&#xff0c;还有很重要的就是要对空间物体的关系、比例、光影关系都要理解透彻。大体快可分割成多个x小体块。其实当年学习的绘画基础也是画好手绘的基础&#xff0c;画手绘依然需要去理解整体画面的空间黑白灰、物体穿插…

internetreadfile读取数据长度为0_【完结】TensorFlow2.0 快速上手手册

大家好&#xff0c;这是专栏《TensorFlow2.0》的第五篇文章&#xff0c;我们对专栏《TensorFlow2.0》进行一个总结。我们知道全新的TensorFlow2.0 Alpha已经于2019年3月被发布&#xff0c;新版本对TensorFLow的使用方式进行了重大改进&#xff0c;为了满足各位AI人对TensorFlow…

Facial Landmark Detection(人脸特征点检测)

原文地址&#xff1a;http://www.learnopencv.com/facial-landmark-detection/#comment-2471797375 作为计算机视觉研究员&#xff0c;我们很早就开始研究人脸。人脸分析领域最广为人知的就是人脸识别&#xff08;face recognition&#xff09;.但是为了识别一幅图像中的人脸&…

Java中的Error和Exceptiond的异同点

Error和Exception的异同点&#xff1a; &#xff08;1&#xff09;Error类和Exception类都继承超类Java.lang.Throwable &#xff08;2&#xff09;Error&#xff1a;一般指与虚拟机相关的问题&#xff0c;如系统崩溃&#xff0c;内存溢出等。对于这类错误&#xff0c;仅靠程序…