Hash表实现原理

news2024/11/24 1:50:35

Hash表查找的本质就是:在创建记录表的时候,确定记录的key与其存储地址之间的关系f,当要查找key=k的记录时,通过关系 f 就可得到相应记录的地址而获取记录,从而免去了key的比较过程

我们把这个关系 f 称为Hash 函数(或者散列函数),记为 H(key)。


目录

1、构造Hash函数的方法

(1) 保留除数法

(2) p 是一个质数的原因

2、如何选取合适的p值(如何选择Hash表的长度)

3、处理冲突的方法

(1) 开放地址法

(2) 链式存储法


1、构造Hash函数的方法

构造Hash函数的方法有很多,原则上都是尽可能将这些记录均匀分布,尽量减少冲突现象的发生。(冲突现象指的是 经过Hash函数计算得到的一个地址,但是该地址已经存了其他内容),下面是几种常用的构造方法。

  • 直接地址法
  • 平方取中法
  • 叠加法
  • 保留除数法
  • 随机函数法

下面将重点了解保留除数法。

(1) 保留除数法

保留除数法,又叫做质数除余法,假设一个Hash表的长度为m,选取一个不大于 m 的最大质数p,令

H(key) = key % p

这是 key 和 H(key)最基本的关系,但是p为什么要特地选择一个质数呢?

(2) p 是一个质数的原因

假设现在有这么一组 key值的集合,key:28  35  63  77  105

=》若 p 不是一个质数,假设p = 21 = 3*7,则

H(key) = key % 21:  7   14   0   14    0   

     key = 35、77对应的地址都是 14,说明key = 35、77都打算存到第 14 个位置上,很显然冲突了,这是因为 p 包含了质数因子 7,key=35、77 也包含了7,两者大概率会被映射到相同单元。

=》若 p 不是一个质数,假设p = 19,则

H(key) = key % 19: 9   16   6    1    10

     现在的话,H(key) 的地址分布就好很多了。

2、如何选取合适的p值(如何选择Hash表的长度)

p 是一个不大于 m 的最大质数,其中 m 是Hash表的长度。选择 p 值本质上就是选择Hash表的长度。为了让表保持一定的空闲余量来缓解冲突,一般满足下面的条件:

α = n / m

  • α 是表的装填因子,一般在 0.7 ~ 0.8 之间;
  • n 是表中允许存放的记录个数
  • m 是Hash表的长度

假设α = 0.75,我们打算在表中存放 75个记录,此时的表长m = 75/0.75 = 100,p是一个不大于m的最大质数,因此 p = 97。

3、处理冲突的方法

从最开始的例子可以发现,两个不一样的key值,经过Hash函数计算得到的结果是一样的,也就是说,有两个key值要存放到同一个位置,这就是所谓的“冲突”。选择 p 为质数只是为了缓解冲突,但是不能避免小概率冲突的发生,处理冲突的方法主要介绍两种:

  • 开放地址法:如果某个位置已经放了其他数据,那就在该位置的前后找一个空闲位置来存放

  • 链式存储法:相互冲突的记录拉成一个链表,记录表里存放链第一个结点的地址。

(1) 开放地址法

开放地址法的基本思路:在原本 H(key) 的基础上获取下一个地址,使用的公式如下

Hi = ( H(key) + i ) % m,i = 1,2,3...

H(key) + i 其实就在 H(key) 后面第 i 个位置的下标,模 m的目的是保证取到的地址在 0 ~ m-1之间

现在 H(key) 的位置已经放了一个数据,但是又有其他数据要放在这个位置,于是向后探索,H(key) + 1 的位置也有其他数据了,继续向后探索,发现H(key) + 2 的位置没有放数据,此时就把数据放在这个位置。

缺点:虽然解决了冲突,但是如果寻找新位置的时候,一直找不到合适的,最坏的情况是找不到新位置,这种情况称为“积聚”,严重影响了Hash表的查找效率。

(2) 链式存储法

发生冲突时,将各冲突记录链在一起,即Hash函数计算结果相同的key值存于同一链表。H(key)对应的 HPi 存放的是第一个结点的地址,如果没有结点,那就为空。

优点:无聚积现象;删除表中记录容易实现

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

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

相关文章

1.3 字符编码

文章目录1. 编码2. ASCII 字符集3. 字符编码发展4. Unicode 字符集5. 字符编码5.1 UTF-165.3 UTF-325.3 UTF-86. 文件编码转换7. 乱码问题1. 编码 计算机只能识别高低电平, 将高低电平用数字表示: 0表示低电压, 1表示高电平. 于是就创造出来二进制数, 一个二进制有 0 和 1, 两…

【网络工程】5、路由器介绍及配置实操

接上篇《4、企业级交换机配置》 之前我们通过eNSP完成了一个企业级交换机的配置实例,本篇我们继续来讲解网络设备——路由器的介绍,以及完成路由器的相关配置实操。 当我们申请了一条宽带后,一般都需要一台路由器来进行上网,那么…

SpringBoot项目创建及其核心设计思想

参考了很多相关博客: springboot怎么学? - 知乎 如何解读springboot 中约定大于配置、JPA是什么、咋用_打豆豆。的博客-CSDN博客 SpringBoot约定大于配置到底是什么意思?_zhupanlinch的博客-CSDN博客 SpringBoot约定大于配置的特性解读 & SpringBoot…

胶囊网络深入理解

胶囊网络的概念与理解 胶囊网络概述 人工神经元不应当追求神经元活动中的视角不变性,(使用单一的标量输出来总结一个局部池中的重要特征的检测器的活动)。而应当使用局部的胶囊,这些胶囊对其输入执行一些相当复杂的内部计算。然…

【Java】Java中时间的相关类(Date,SimpleDateFormat)

文章目录Date类SimpleDateFormat类Date类 Date是JDK提供的类,用来描述时间,使用无参构造创建的对象默认表示系统的当前时间,使用有参构造(指定的毫秒值)表示从时间原点(1970年)过了该参数值的时…

08_原始套接字

知识点1【原始套接字概述】 1、UDP封包格式 ​IP封包格式: Ethernet封包格式 TCP封包格式: ICMP封包格式:ping 知识点2【数据包的分析】 案例:网络分析器: 知识点2【混杂模式】接受数据(了解&#x…

win11+WSL2安装visdom

win11WSL2安装visdom环境配置下载visdom小小的修改运行visdom环境配置 Win11WSL2Ubuntu-18.04 下载visdom pip install visdom pip install --upgrade visdom conda install -c conda-forge visdom 小小的修改 \home\grass\miniconda3\envs\torch\lib\python3.8\site-pack…

[一篇读懂]C语言九讲:线性表应用

[一篇读懂]C语言九讲:线性表应用1. 与408关联解析及本节内容介绍1 与408关联解析2 本节内容介绍2. 线性表的顺序表示原理解析1 线性表线性表的定义线性表的特点2 线性表的顺序表示顺序表的定义顺序表优缺点顺序表插入操作顺序表删除操作动态分配3. 顺序表的初始化及…

微服务系列之单体架构

随笔 终于迎来了“微服务、云原生”系列文章,这个系列的文章的更新速度博主无法保证能够每个星期一篇,因为这个系列的难度比以往系列都要高(以往的系列就没有保证一个星期一更)。但是长时间不去写文章,自己可能会慢慢…

Keepalived+LVS部署

目录 一、环境准备 二、实验拓扑 三、部署LVS DR环境 四、LVS服务器配置keepalived 1、安装keepalived 2、修改lvs1服务器keepalived配置 3、修改lvs2服务器keepalived配置 五、客户端测试 1、负责均衡测试 2、LVS服务器高可用测试 一、环境准备 准备4台centos服务器…

学习日记(单元测试、反射、注解、动态代理)

文章目录学习日记(单元测试、反射、注解、动态代理)一、单元测试1. 单元测试实践2. JUnit 常用注解二、反射1. 反射获取类对象2. 反射获取构造器对象3. 反射获取成员变量对象4. 反射获取成员方法对象三、反射的作用举例1. 绕过编译阶段为集合添加数据2. …

基于生物地理学的优化算法(BBO)用于训练多层感知器(MLP)【多种算法进行比较】(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

java中的BigDecimal使用

文章目录1、什么是BigDecimal?2、为什么使用BigDecimal?3、如何使用BigDecimal?(1)BigDecimal初始化赋值(2)加减乘除运算(3)BigDecimal保留两位小数及舍入模式&#xff0…

WFP实现侧边栏导航菜单

菜单导航功能实现,常规的管理系统应该常用,左侧显示菜单条目,点击菜单,右侧切换不同的业务用户控件。 常用菜单可以采用TreeView树形控件特定样式实现 ,本文介绍的是使用ExpanderListView的组合形式实现的导航菜单&am…

算法day24|理论基础77

详细布置 理论基础 什么是回溯法:递归函数下面通常有回溯法 它使用的地方:组合,切割,子集,排列,棋盘问题(N皇后,解数独) 回溯算法的模板: void backtracking(参数)&…

微型计算机基础

微型计算机常用术语 位(bit):计算机所能表示的最基本,最小的数据单元。1个二进制位有两种状态0和1 通常情况下0表示低电平(接地),1表示高电平接电源(VCC) 字节&#xff0…

MATLAB 矩阵处理及多项式计算

一、实验目的 (1)掌握生成特殊矩阵以及矩阵处理的方法 (2)掌握数据统计和分析的方法 (3)掌握多项式的常用计算 二、实验原理与实验设备 原理:计算机编程相关知识技能和MATLAB软件编译环境 …

c++——map和set的封装

注:该封装基于前面博客已实现红黑树,map和set封装并不难,主要还是对红黑树的理解 目录 一. 改造红黑树 1. 改变节点的定义,使用更高维度的泛型 2. 红黑树追加迭代器的实现 1. 红黑树迭代器的构造函数和基本框架 2. begin()和e…

2.4、编码与调制

2.4、编码与调制 在计算机网络中。计算机需要处理和传输用户的文字,图片,音频和视频。它们可以统称为消息。 数据是运送消息的实体。 计算机中的网卡将比特 000 和 111,变换成相应的电信号发送到网线。 也就是说,信号是数据的…

[附源码]java毕业设计网络学习平台

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