7-6散列查找(数据结构)_散列表的比较次数怎么算-程序员宅基地

技术标签: 哈希函数  散列表  散列  数据结构  哈希表  

一.基础知识
1.查找——散列结构——散列表/哈希表
2.同义词:不同的关键字通过散列函数映射到同一个值,它们为“同义词”
在这里插入图片描述
3.冲突:该位置已经存放了元素,这就产生了冲突
4.解决冲突:拉链法/链地址法
将同义词存储在链表中
在这里插入图片描述
对于同义词各个关键字之间可以乱序(蓝色竖着),但如果进行排序,对链表进行顺序查找时会提高查找效率
在这里插入图片描述
二.散列查找
给出散列函数H(key)=key%13
给出关键字{19,14,23,1,68,20,84,27,55,11,10,79}
14%13=1,放在1号框,其他同理
在这里插入图片描述
(1)查找55
55%13=3,在3号框往下找,依次找到68,55,查找成功,查找长度为2
注:
查找长度:对比次数
(2)查找21
21%13=8,8号位为空,查找失败
查找长度:0
注:对比0次
(3)查找66
66%13=1,在1号框往下找,依次找到14,1,27,79,查找失败
查找长度:4
注:对比4次

三.效率分析ASL

ASL成功=(1×6+2×4+3+4)/12=1.75(横向计算)
ASL成功=[(1+2+3+4)+(1+2)+(1+2)+…]/12=1.75(竖着计算)
注:可以发现,每个框一个关键字时,效率最高
ASLmin=(1+1+1+…+1)/12=1
因此要尽可能的减少冲突
在这里插入图片描述
一个个框看查找长度(对比次数),一共13个框
ASL失败=(0+4+0+2+0+0+2+1+…)/13=0.92
可以看到,分子为蓝色框之和,分母为表长
即:ASL失败=表中记录数/散列表长度
我们称α为装填因子,α=表中记录数/散列表长度
显然:装填因子直接影响散列表的查找效率,为了提高查找效率,设计合理的散列函数就显得十分重要

四.常见的散列函数
设计目标:让不同关键字的冲突尽可能少

1.除留余数法H(key)=key%p
m:散列表表长
p:一个不大于m的最大质数(通常情况下,具体问题具体分析)
质数/素数:在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。如:2、3、5、7

举例:
表长m=13,p取13
表长m=15,p取13

2.直接定址法
H(key)=key或H(key)=a*key+b
其中a和b为常数
优势:不会产生冲突
缺点:占用空间过大
适合:关键字分布基本连续,否则会浪费空间
举例:存储一个班级同学的学生信息
每个学号和1120112176作差,得到0,1,2,3…
在这里插入图片描述
3.数字分析法
适合:分布均匀
举例:手机号
在某些位上分布均匀,某些位上分布不均匀
可以将手机号后四位作为散列地址
在这里插入图片描述
在这里插入图片描述
4.平方取中法
关键字平方,然后取中间几位
适合:关键字每位取值都不够均匀或均小于散列地址所需位数
举例:存储身份证号
身份证号平方,然后取中间5位
这样分布就比较均匀(≠不冲突)
在这里插入图片描述
在这里插入图片描述
总结
在这里插入图片描述
五.解决冲突的另一个方法:开放定址法

Hi=(H(key)+di)%m
i=0,1,2,3,…,k (k≤m-1)
m:表长
di:增量序列
i:第i次发生冲突

(一)线性探测法

1.基本概念

di=0,1,2,3,…,m-1
在这里插入图片描述
插入1,H(key)=1%13=1发生冲突
表长m=16
H0=(1+d0)%16=1依然冲突
继续计算H1=(1+d1)%16=2
成功放入
这表示空闲地址既向它的同义词开放,也向它的非同义词开放
在这里插入图片描述
继续,企图放入84
在这里插入图片描述
H(key)=84%13=6冲突
H1=(6+1)%16=7冲突
H2=(6+2)%16=8成功放入
在这里插入图片描述
放入27
在这里插入图片描述
H(key)=27%13=1冲突
H1=(1+1)%16=2冲突
H2=(1+2)%16=3冲突
H3=(1+3)%16=4成功放入
在这里插入图片描述
其他同理,如果再想放入25
在这里插入图片描述
H(key)=25%13=12冲突
H1=(12+1)%16=13成功放入
在这里插入图片描述
如果再想放入数据,最大到表长15
Hi=(H(key)+di)%16
即:冲突处理函数值域为[0,15]

对于散列函数H(key)=key%13
散列函数值域[0,12]

2.查找操作

(1)查找27
27%13=1,匹配失败
H1=2,匹配失败
H2=3,匹配失败
H3=4,匹配成功
查找长度:4
在这里插入图片描述
(2)查找11
11%13=11,匹配成功
查找长度:1
在这里插入图片描述
(3)查找21
21%13=8匹配失败
H1=9匹配失败
H2=10匹配失败
H3=11匹配失败
H4=12匹配失败
H5=13匹配失败
与拉链法的空指针不同,这里空白处也记一个元素,与空位置相比也算一次比较
查找长度:6
在这里插入图片描述
(4)查找21
21%13=8匹配失败
H1=9匹配失败
H2=10匹配失败
对比完空位置,查找结束
查找长度:3
在这里插入图片描述
3.删除操作

删除1,1空出,想要查找27时
27%13=1匹配失败
H1=2匹配是吧,遇到空白结束
未成功找到4号位的27
在这里插入图片描述
在这里插入图片描述
因此在删除1后需要告诉计算机1位置有东西(做一个删除标记,进行逻辑删除),查找时还需要继续往后找
在这里插入图片描述
缺点:删除元素过多时还需要一个个对比
查找79
79%13=1
H1、H2…H9成功
8次冲突,对比关键字9次
在这里插入图片描述
4.查找效率分析ASL

ASL成功=(1+1+1+2+4+1+1+3+3+1+3+9)/12=2.5
在这里插入图片描述
在这里插入图片描述
查找失败需要走到底
初次探测地址H0只能在[0,12]
要查找的关键字映射到0的位置:需要对比1次
要查找的关键字映射到1的位置:需要对比13次

要查找的关键字映射到12的位置:需要对比2次
ASL失败=(1+13+12+11+10+9+8+7+6+5+4+3+2)/13=7

:若用mod表示key%13中的13
这里的分子的个数是mod(从0~mod-1),分母的值也是mod;而查找成功的分母为元素个数(12)

例:现有长度为 11 且初始为空的散列表 HT,散列函数是 H(key) = key % 7,采用线性探查 (线性探测再散列)法解决冲突。将关键字序列 87, 40, 30, 6, 11, 22, 98, 20 依次插入 HT 后, HT 查找失败的平均查找长度是 :(9+8+7+6+5+4+3)/7=6

(二)平方探测法

1.基本概念
di=0,1,-1,4,-4,9,-9
在这里插入图片描述
表长27
(1)插入19
19%13=6,冲突
H1=(6+1)%27=7成功插入
(2)插入32
32%13=6,冲突
H1=(6+1)%27=7冲突
H2=(6-1)%27=5成功插入
在这里插入图片描述
插入84
84%13=6
H1=7冲突
H2=5冲突
H3=10冲突
H4=2冲突
H5=(6+9)%27=15冲突
H6=(6-9)%27=(-3)%27=24
注:(-3)=(-1)×27+24
mod也把表看成循环表,6往左移动9位,5,4,3,2,1,0,26,25,24
在这里插入图片描述
插入成功
在这里插入图片描述
2.查找

查找71
在这里插入图片描述
71%13=6匹配失败
H1=7匹配失败
H2=5匹配失败
H3=10匹配失败
H4=2匹配失败
H5=15匹配成功

3.其他
平方探测法散列表的长度m必须可以表示成4j+3的素数,才能探测到所有位置
如:m=4×1+3=7可以
m=8不可以

(三)伪随机序列法

di是一个伪随机序列

如:di=0,5,24,11…
举例:
在这里插入图片描述
总结
在这里插入图片描述
六.再散列法

除了原始的散列函数H(key)之外,多准备几个散列函数,当散列函数冲突时,用下一个散列函数计算一个新地址,直到不冲突为止
Hi=RHi(key)
i=1,2,3,…,k

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45825865/article/details/117231639

智能推荐

OpenCV+python轮廓-程序员宅基地

文章浏览阅读550次。OpenCV中的轮廓1.1什么是轮廓轮廓可以简单认为成连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。为了准确,要使用二值化图像。需要进行阀值化处理或者Canny边界检测。查找轮廓的函数会修改原始图像。如果之后想继续使用原始图像,应该将原始图像储存到其他变量中。在OpenCV中,查找轮廓就像在黑色背景中超白色物体..._opencv 轮廓

【易经】-- 风水基础-程序员宅基地

文章浏览阅读1.2k次,点赞39次,收藏24次。八字源自古代的中国,是一种利用天干和地支来准确记录年、月、日、时的方式,由“年干,年支”、“月干,月支”、“日干,日支”、“时干,时支”,共八个干支所组成(共八个字),年、月、日、时的干支组合称为“柱”,形成“年柱”、“月柱”、“日柱”、“时柱”,故八字又称为“四柱”或“四柱八字”。

vscode通过跳板连接远程服务器docker容器_通过跳板机拉取docker-程序员宅基地

文章浏览阅读2.5k次。目的:深度学习不能在本机跑吧,丢服务器上,那怎么debug呢??曾经的我全靠print…下载vscode,安装remote-ssh插件不详细说了…docker内配置ssh在目标服务器里开一个docker容器,用-p把容器的端口22转到服务器的5222:docker run --name 容器名字 -it -p 5222:22 --shm-size 64G --rm --gpus all -v 挂载目录 容器名字 bash【远程服务器容器】设置 root 账户密码:passwd r_通过跳板机拉取docker

138. 复制带随机指针的链表--PYTHON_python 复制带随机指针的链表-程序员宅基地

文章浏览阅读156次。自己1:嘿嘿,首先想到的就是python库中的copy,哈哈,作弊一把"""# Definition for a Node.class Node: def __init__(self, x, next=None, random=None): self.val = int(x) self.next = next self.random ..._python 复制带随机指针的链表

学习Qss--背景属性_qt qss设置背景-程序员宅基地

文章浏览阅读487次。取值:Brush类型作用:设置控件的背景颜色,默认是border之内的矩形区域,包括内边距和内容矩形。_qt qss设置背景

js使用canvas实现图片鼠标滚轮放大缩小拖拽预览,显示像素坐标,显示像素值_canvas图片拖动,鼠标滚轮放大缩小-程序员宅基地

文章浏览阅读777次,点赞4次,收藏13次。todo 实现画矩形框,圆形roi。_canvas图片拖动,鼠标滚轮放大缩小

随便推点

python理论知识及python解释器多个版本共存和pycharm安装-程序员宅基地

文章浏览阅读592次,点赞17次,收藏11次。编程语言就是人与计算机之间的语言计算机就是通电的机器能够批量处理人类指令和数据的智能设备系统软件就是建立在硬件上的软件,负责调度整个硬件功能包括调度计算机服务、读取文件、进程管理...系统自带的服务,例如网卡服务、文件管理器机器语言就是计算机可以理解的语言由于计算机基于点工作,点又分为高低电频,0为低,1为高我们可以控制高低电频的变化组成一系列的指令去操作我们的系统硬件机器语言因为他能直接操作计算机硬件,所以他是最低级的计算机语言汇编语言其实就是用一个英文字母或者一串单词来代表机器语言。

'xxx' is not a commit and a branch 'xxx' cannot be created from it_release-23.4' is not a commit and a branch 'origin-程序员宅基地

文章浏览阅读968次。问题我们想在一个库origin的dev分支上开发,就必须创建远程origin的dev分支到本地,于是我们用这个命令创建本地dev分支:$ git checkout -b dev origin/dev然后就报错了原因大部分原因是因为我们的远端origin并没有dev这个分支,所以你不可能创建他的本地副本解决方案在github手动创建一个dev分支,然后再使用该语句将远端分支的副本创建..._release-23.4' is not a commit and a branch 'origin/release-23.4' cannot be c

spring_mvc(三)Obtaining Request Data-程序员宅基地

文章浏览阅读67次。[color=blue]Obtained 'foo' query parameter value 'bar'[/color]http://localhost:8080/spring_mvc_test/data/param?foo=test[code="java"]@RequestMapping(value="param")public @ResponseBody String wi..._四、obtaining request data

HTML+CSS学习总结 — 设计登录注册界面_html会员注册页面实验报告-程序员宅基地

文章浏览阅读2.2k次,点赞6次,收藏60次。一、HTML页面代码如下:登录界面<!DOCTYPE html><html lang="zh-cn"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>登陆界面</title> <link rel="stylesh_html会员注册页面实验报告

css选择器权重及其计算规则_权重为1和权重为2哪个好-程序员宅基地

文章浏览阅读1.8k次,点赞4次,收藏8次。css选择器文章目录css选择器选择器类型css选择器权重值权重计算方法案例选择器类型ID  #idclass  .class标签  p通用  *属性  [type=“text”]伪类  :hover伪元素  ::first-line子选择器、相邻选择器css选择器权重值选择器权重!important权重!..._权重为1和权重为2哪个好

题目:探索PreQuest:一款强大的前置任务管理工具-程序员宅基地

文章浏览阅读326次,点赞3次,收藏4次。题目:探索PreQuest:一款强大的前置任务管理工具项目地址:https://gitcode.com/xdoer/PreQuest项目简介PreQuest 是一个精心设计的开源项目,旨在帮助开发者和团队更有效地管理和跟踪软件开发过程中的前置任务。它是一个轻量级、灵活且易于集成的解决方案,可让你专注于复杂项目的关键路径,确保每个步骤按部就班地完成。技术分析PreQuest是用Python...