Hash表(哈希表、散列表)

news2024/11/29 0:30:01

哈希表

概念

为什么需要哈希表

静态查找表与动态查找表中,为了查找某关键字值等于某个值的记录,都要经过一系列的关键字进行比较,以确定待查记录的储存位置或查找失败,查找的时间总是与比较次数有关

什么是哈希表

哈希表,也叫散列表,英文Hash table,是根据关键码值而直接进行访问的数据结构。

哈希表的基本思想

  • 将记录的存储位置与它的关键字之间建立一个确定的关系H,使每个关键字和唯一的存储位置对应。而这种关系H就是该哈希表的一个哈希函数。
  • 在查找时,只需要根据对应关系计算出给定的关键字值H(k),就可以得到记录的存储位置。这样,不经过比较,一次存取就能得到所查元素的查找方法。

哈希表相关术语

  • 哈希函数:在记录的关键字与记录的存储地址之间建立的一种对应关系。
  • 冲突: 若关键字不同而函数值相同,则称这两个关键字为“同义词”,并称这种现象为冲突。
  • 哈希查找:利用哈希函数进行查找的过程。
  • 装填因子:记表中添入记录数为 m m m,表长度为 n n n,则装填因子为 α = m n \alpha = \frac{m}{n} α=nm

哈希表性质

  • 哈希表实际上是以空间换取时间,它的查找的时间效率一般比其它方法高,但消耗空间资源
  • 冲突一般不可避免,发生冲突的次数与表的装填程度呈正相关
  • 哈希函数相同的情况下,处理冲突的方法不同,所得哈希表的平均查找长度也不同
  • 线性探测再散列处理冲突容易造成记录的“二次聚集”,即使得本不是同义词的关键字又产生新的冲突
  • 对开放定址处理冲突的哈希表而言,表长必须≥记录数
  • 链地址处理冲突的哈希表不要求表长必须≥记录数,它的平均查找长度主要取决于哈希函数本身

构造哈希函数

构造哈希函数的方法有很多,但比较常用的有除留余数法、平方取中法等,需要根据数据的特性以及其它需要来选取

直接定址法

直接定址法取关键字本身或关键字某个线性函数作为哈希表的地址

设其关键字为 k k k,那么线性表示的公式如下
H ( k ) = a k + b H(k) = ak+b H(k)=ak+b
该方法所得地址集合与关键字大小相等,不会发生冲突

适用情况:

  • 给定的一组关键字为关键字集合中全体元素,若不是全体关键字,则必有某地址单元空闲

数字分析法

如果可能出现的关键字的数位相同,且取值事先知道,则可对关键字进行分析,取其中“分布均匀”的若干位或它们的组合作为哈希地址。

例如有80个记录,关键字为8位十进制数,哈希表表长为100,即地址范围为 [ 0 , 99 ] [0,99] [0,99]

已知关键字如下图

对其进行分析,发现各个数字一号位置只取8,二号位置只取1,三号位置只取3、4,八号位置只取2、7、5。然而四、五、六、七号位置数字分布近乎随机。

故取四、五、六、七号位置数字任意两位或两位与另外两位叠加后得到的数字作为哈希地址。

适用情况:

  • 关键字位数比哈希地址位数大,且可能出现的关键字事先知道的情况。

平方取中法

如果关键字的所有各位分布都不均匀,则可取关键字的平方值的中间若干位作为哈希表的地址。由于一个数的平方值的中间几位数受该数所有位影响,因此得到的哈希地址的分布均匀性要好一些,冲突要少一些

例如,为标识符建立一个哈希表,假设标识符为一个字母或一个字母和数字。在计算机内用两位八进制数表示字母和数字,其利用平方取中法得到的关系如下图

适用情况:

  • 适于不知道全部关键字情况
  • 常用此法求取哈希函数

折叠法

若关键字的位数很多,且每一位上数字分布大致均匀,则可采用移位叠加或间界叠加。即将关键字分成若干部分,然后以它们的叠加和(舍去进位)作为哈希地址。

  • 移位叠加是将分割后的每一部分的最低位对齐,然后相加
  • 间界叠加是从一端向另一端沿分割界来回折叠,然后对齐相加

例如存在关键字0442205864,规定哈希地址位数为4,则利用上述两种叠加方法得到的地址可如下图

适用情况:

  • 适于关键字位数很多,且每一位上数字分布大致均匀情况

除数留余法

该方法很简单,以关键字被某个数p除后所得余数作为哈希地址。

同样设k为关键字,p 为不大于表长的素数或不包含小于20的质因素的合数,公式如下
H ( k ) = k m o d    p H(k) = k\mod{p} H(k)=kmodp
其中p的选取非常重要,如果选不好,则容易产生同义词。

随机数法

当关键字不等长时,可取关键字的某个伪随机函数值作为哈希地址。

公式如下:
H ( k ) = r a n d o m ( k ) H(k) = random(k) H(k)=random(k)
适用情况:

  • 适于关键字长度不等的情况

解决冲突

在上文中提到,使用某种方法构造出的哈希函数,对于不同关键字可能存在相同的函数值,所以这种情况就要解决冲突。

开放定址法

当冲突发生时,形成一个探查序列;沿此序列逐个地址探查,直到找到一个空位置(开放的地址),将发生冲突的记录放到该地址中。

公式如下:
H i = ( H ( k ) + d i ) m o d    m i = 1 , 2 , 3 , . . . , k   ( k ≤ m − 1 ) H_i = (H(k)+d_i)\mod{m} \\i = 1,2,3,...,k\space(k\le m-1) Hi=(H(k)+di)modmi=1,2,3,...,k (km1)
其中 k k k为关键字, m m m为哈希表表长, d i d_i di为增量序列

根据增量序列的取值不同,可以分为三类方法

  • 线性探测再散列: d i = 1 , 2 , . . . , m − 1 d_i=1,2,...,m-1 di=1,2,...,m1
  • 二次探测再散列: k < m 2 ,   d i = 1 2 , − 1 2 , 2 2 , − 2 2 , . . . , ± k 2 k< \frac{m}{2}, \space d_i=1^{2},-1^{2},2^2,-2^2,...,\pm k^2 k<2m, di=12,12,22,22,...,±k2
  • 伪随机探测再散列: d i d_i di为伪随机数序列

例如表长为11的哈希表已经填有关键字为17、60、29的记录,其哈希函数为 H ( k ) = k m o d    11 H(k)= k \mod{11} H(k)=kmod11,现将一关键字为38的新记录填入哈希表,利用上述三种方法得到的过程与结果分别如下

线性探测再散列

二次探测再散列

伪随机探测再散列

链地址法

将所有关键字为"同义词"的记录链接在一个线性链表中。此时的哈希表以"指针数组"的形式出现,数组内各个分量存储相应哈希地址的链表的头指针

再哈希法

构造若干个哈希函数,当发生冲突时,用另一个哈希函数计算另一个哈希地址,直至不发生冲突为止。

该方法需要预先设置一个哈希函数序列,另外它的计算时间相对增加了。

溢出区法

建立两个表,一个是基本表,另一个是溢出表(存放所有关键字和基本表中关键字冲突的记录,一旦冲突发生,就存入溢出表)。

平均找查长度ASL

找查长度

按照关系一次就找到元素位于哈希表中的位置,即成功找查长度记为1,如果第一次找查的位置不是相应的数字,则应该根据上文中的方法继续比较查找,并且次数依次加1。

如果上述操作最终没有找到该元素,则最后累计的长度为失败找查长度。

平均找查长度

ASL(Average Search Length),即平均查找长度,在查找运算中,由于所费时间在关键字的比较上,所以把平均需要和待查找值比较的关键字次数称为平均查找长度
A S L = ∑ i = 1 n p i c i ASL = \sum_{i=1}^{n} p_ic_i ASL=i=1npici
其中 p i p_i pi为第i个元素的概率; c i c_i ci是找到第i个元素的比较次数。

当然,平均找查长度有平均成功找查长度平均失败找查长度

在讨论ASL时,我们一般各元素概率相等,即 p i = 1 n p_i= \frac{1}{n} pi=n1

此时的平均找查长度为
A S L = 1 n ∑ i = 1 n c i ASL=\frac{1}{n}\sum_{i=1}^{n} c_i ASL=n1i=1nci

几种方法的ASL

在等概率条件下,可以给出上文中提到的几种方法的平均成功找查长度和平局失败找查长度(此处不做证明)

线性探测再散列

平均成功找查长度:
S n l ≈ 1 2 ( 1 + 1 1 − α ) S_{nl} \approx \frac{1}{2}(1+\frac{1}{1- \alpha}) Snl21(1+1α1)
平均失败找查长度:
U n l ≈ 1 2 ( 1 + 1 ( 1 − α ) 2 ) U_{nl} \approx \frac{1}{2}(1+ \frac{1}{(1-\alpha)^2}) Unl21(1+(1α)21)

随机探测再散列、二次探测再散列和再哈希

平均成功找查长度:
S n r ≈ − 1 α l n ( 1 − α ) S_{nr} \approx -\frac{1}{\alpha}ln(1-\alpha) Snrα1ln(1α)
平均失败找查长度:
U n r ≈ 1 1 − α U_{nr} \approx \frac{1}{1-\alpha} Unr1α1

链地址

平均成功找查长度:
S n c ≈ 1 + α 2 S_{nc} \approx 1+\frac{\alpha}{2} Snc1+2α
平均失败找查长度:
U n c ≈ α + e − α U_{nc} \approx \alpha + e^{-\alpha} Uncα+eα

代码

关于哈希表的一个简单使用可以参考之前的文章

哈希排序算法 - 菜缤的世界 CairBin’s Blog

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

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

相关文章

[附源码]java毕业设计校园征兵及退役复原管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

视听杂志视听杂志社视听编辑部2022年第11期目录

专题:对外传播 共塑与去精英化&#xff1a;国家形象建构的实践创新——基于纪录片《柴米油盐之上》的多模态分析 董星雨;程欣;刘苏情; 3-7《视听》投稿&#xff1a;cnqikantg126.com 网络赋权下抖音国际版TikTok的海外传播策略探析 吴梦玲; 7-10 以画对话&#xff…

m3u8 文件格式详解

简介 M3U8 是 Unicode 版本的 M3U&#xff0c;用 UTF-8 编码。"M3U" 和 "M3U8" 文件都是苹果公司使用的 HTTP Live Streaming&#xff08;HLS&#xff09; 协议格式的基础&#xff0c;这种协议格式可以在 iPhone 和 Macbook 等设备播放。上述文字定义来自于…

一文玩转Java 泛型知识

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;前端开发者…

青岛品质水稻共养 国稻种芯·中国水稻节:山东西海岸收获季

青岛品质水稻共养 国稻种芯中国水稻节&#xff1a;山东西海岸收获季 半岛全媒体记者 孟达 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康大会报道&#xff1a;山东青岛西海岸新区王…

发了3000个短视频作品才总结出的9点快速破播放的技巧

大家好&#xff0c;我是我赢助手&#xff0c;专注于自媒体短视频去水印、去重和文案提取运营。 今天给大家分享下发了3000个短视频作品才总结出的9点快速破播放的技巧&#xff1a; 1、前期养号: 新号创建前7天不要急着发作品&#xff0c;刷兴趣标签养号&#xff0c;能让账号…

【机器学习】数据驱动方法在电网稳定分析应用浅谈

目录 一、数据驱动概述 二、数据驱动特点 三、数据驱动与其他方法对比 四、总结 五、参考文献 一、数据驱动概述 数据驱动在电力系统稳定分析中的应用&#xff0c;主要目标是从电网运行数据角度建立电力系统稳定分析模型&#xff0c;以数据之间的关联性分析视角挖掘电力系…

MySQL数据库期末考试试题及参考答案(08)

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 一、 填空题 MySQL用户变量由符号____和变量名组成。MySQL中____循环语句会无条件执行一次语句列表。DELIMITER语句可以设置MySQL的____。MySQL中打开游标使用____关键字。…

基于PaddleOCR的集装箱箱号检测识别

基于PaddleOCR的集装箱箱号检测识别 项目背景 国际航运咨询分析机构 Alphaliner 在今年 3 月公布的一组数据&#xff0c;2021 年集装箱吞吐量排名前 30 的榜单中&#xff0c;上海港以 4702.5 万标箱的「成绩单」雄踞鳌头。 较上一年同期&#xff0c;上海港集装箱吞吐量增长 8…

在host上窥探kvm虚拟机内存

1. kvm内存虚拟化 kvm虚拟机的内存虚拟化&#xff0c;使用了内存转换技术&#xff0c;过程如下&#xff1a;GVA -> GPA -> HVA -> HPA 通过qemu启动了一个8G内存的虚拟机&#xff0c;查看内存smaps&#xff0c;可以发现有个内存就是8G&#xff0c;这个就是guest所使用…

Pioneer | X METAVERSE PRO Explores the New Value of “Mining + Finance“

“The mining boom driven by Bitcoin has created many wealth myths: miners can earn 50 BTC every 10 minutes at that time. If you successfully get a Bitcoin block and hold it since 2009, you will have BTC worth $827,930 in your wallet by 2022. “ Cryptocurr…

AE插件:Composite Brush Mac(画面颜色选取替换修改)

Composite Brush for Mac是一款由AEscripts出品的AE画面颜色选取替换修改插件&#xff0c;可以直接在视频画面上选取颜色&#xff0c;然后对选择部分修改替换成自己需要的颜色&#xff0c;有了Composite Brush插件用户可以直接在视频画面上选取自己想要的颜色。 单击并拖动&am…

图像运算和图像增强十一

图像运算和图像增强十一 图像锐化之 Scharr、Canny、LOG 实现边缘检测 &#xff08;1&#xff09;Scharr算子 Scharr算子又称为Scharr滤波器&#xff0c;也是计算x或y方向上的图像差分。Scharr 算子的函数原型如下所示&#xff0c;和 Sobel 算子几乎一致&#xff0c;只是没有…

服务器的区别跟服务器被攻击了怎么解决

大陆服务器都是需要备案的&#xff0c;想必这是众所周知的&#xff0c;备案的过程繁琐且严格。除此之外&#xff0c;备案还有期限的限制&#xff0c;若网站没有在规定的期限内完成备案&#xff0c;可能会导致我们不能在相应的时间内完成建站。而海外服务器是不存在备案的问题的…

【读论文】DIVFusion: Darkness-free infrared and visible image fusion

【读论文】DIVFusion: Darkness-free infrared and visible image fusion介绍网络结构SIDNet损失函数TCEFNetGRM&#xff08;梯度保持模块&#xff09;CEM&#xff08;对比度增强模块&#xff09;损失函数总结参考论文&#xff1a;https://www.sciencedirect.com/science/artic…

IPv6与VoIP——ipv6接口标识与VoIP概述

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.ipv6接口标识符 1.IPv6接口标识符有以下几种 基于EUI-64地址…

[附源码]java毕业设计校园一卡通管理信息系统台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Go:交互式提示工具go-prompt简介

文章目录简介一、代码示例二、使用go-prompt的项目三、特性1. 强大的自动完成2. 灵活的功能选项3. 快捷键4. 历史记录5. 跨平台支持小结简介 受python提示工具包的启发&#xff0c;在Go中构建强大的交互式提示 一、代码示例 package mainimport ("fmt""githu…

Oracle在Logstash需求中碰到的问题处理方式

Oracle对空值(NULL)的5种处理 在公司Logstash相关需求中,为了方便sql语句更加简洁,所以需要使用到Oracle中的视图,在视图创建过程中,遇到有关对Null值的处理,这里做一个整理,方便日后查询 COALESCE函数 COALESCE&#xff08;expr1&#xff0c;expr2&#xff0c;expr3&#x…

【python】PyQt5的环境搭建和使用

什么是pyQT pyqt是一个用于创建GUI应用程序的跨平台工具包&#xff0c;它将python与qt库融为一体。也就是说&#xff0c;pyqt允许使用python语言调用qt库中的API。这样做的最大好处就是在保存了qt高运行效率的同时&#xff0c;大大提高开发效率。因为&#xff0c;使用python语…