【数据结构】-----哈希

news2024/11/13 10:17:37

目录

一、哈希表概念

二、哈希函数

三、哈希冲突

Ⅰ、定义

 Ⅱ、解决

①闭散列--开放定址法

线性探测

 二次线性探测

②开散列--链地址法(哈希桶)

问题:哈希表何时扩容?


一、哈希表概念

哈希表又称散列表,它是一种数据存储结构,该结构主要是通过某种哈希函数将元素的存储位置与元素的关键码(值)之间建立起一种一一映射的关系。因此在查找时能够通过该哈希函数直接找到对应的元素,效率上明显提高。

例如:存在数据集合{1,3,6,2,4};

哈希函数设置为:hash(key)=key % capacity。capacity为存储元素底层空间总大小。

假设这里的capacity大小为10,则各元素之间的存储位置如下:

用该方法进行搜索不必进行多次关键码的比较,因此速度会很快!

在理想情况下:哈希表的查找可以达到O(1)。而顺序查找和平衡树中,因为值和位置之间没有直接的关系,查找需要进行多次比较,顺序查找O(N),平衡树查找为树的高度,即O(log_2N)。搜索的效率取决于元素的比较次数,相比于哈希,挺慢!

二、哈希函数

哈希函数设计的原则:

  • 哈希函数的定义域必须包括需要存储的全部关键码,而如果散列表允许有m个地址时,其值域必须在0到m-1之间
  • 哈希函数计算出来的地址能均匀分布在整个空间中
  • 哈希函数应该比较简单

 常见哈希函数: 

  • 直接定址法(常用)

取关键字的某个线性函数为散列地址:Hash(Key)=key 或者 Hash(Key)= A*Key + B
优点:简单、均匀
缺点:需要事先知道关键字的分布情况
使用场景:适合查找比较小且连续的情况

  • 除留取余法(常用)

 设散列表中允许的地址数为m(空间总容量),取一个不大于m,但最接近或者等于m的质数p作为除数,按照哈希函数:Hash(key) = key% p(p<=m),将关键码转换成哈希地址。

优点:使用十分广泛,不受限制。

缺点:存在哈希冲突,哈希冲突越多,效率越低。

  • 平方取中 

 假设关键字为123,平方后15129,抽取中间3位512作为哈希地址。

再如关键字4321,平方后18671041,抽取中间3位671或者710作为哈希地址。

该方法适用于:不知道关键字的分布情况,而位数又不是很大的情况。

  • 折叠法 

折叠法是将关键字从左到右分割成位数相等的几部分(最后一部分位数可以短些),然后将这
几部分叠加求和,并按散列表表长,取后几位作为散列地址。

适用于:不知道关键字的分布情况,而位数多的情况。

如:123456789  ->分割:123|456|789 ->相加:123+456+789=1368

假设表长为10,那就取后两位68作为哈希地址。

  • 随机数法 

 选择一个随机函数,取关键字的随机函数值为它的哈希地址,即Hash(key) = random(key),其中random为随机数函数。
通常应用于关键字长度不等时采用此法

用得多还是前面两个,其他简单了解即可! 

三、哈希冲突

Ⅰ、定义

所谓哈希冲突,就是不同的关键码通过同一个哈希函数计算得到相同的存储地址。即相同位置上存在不同的值的现象。

引起哈希冲突的原因可能就是:哈希函数设计不合理引起的!

例如:在上述例子再插入11,计算后得到的地址为下标1,和原来的1发生的冲突,那么该怎么去解决呢?

 Ⅱ、解决

常见两种方法:闭散列 和 开散列

①闭散列--开放定址法

此法又称开放定址法,当发生哈希冲突时,如果哈希表未装满,说明有空位置,那么可以把key存放到冲突位置的下一个空位置去,这里寻找下一个空位置的方法又有两种

  • 线性探测

 这种方式是从发生冲突的位置开始,依次向后探测,直到发现下一个空位置为止

H=(Hash0+i)%m ,i=1,2,3……

Hash0:通过散列函数Hash(x)对元素的关键码 key 进行计算得到的位置,即Hash(key)

m:散列表长度,这里取余,是为防止越界从而达到循环的效果。。

例如:上述例子插入11,通过哈希函数取余操作后发现和原来的1的位置冲突了,那就要继续向后探测,依次+1,+2,……,直到发现空位置,就放入该位置!

优点:实现简单

缺点:一旦发生哈希冲突,所有的冲突连在一起,容易产生数据“堆积”,即:不同
关键码占据了可利用的空位置,使得寻找某关键码的位置需要许多次比较,导致搜索效率降
低。所以需要扩容操作!

  •  二次线性探测

这种探测方式能够避免线性探测的数据堆积问题的,它和线性探测的区别就是:依次跨越i^2 个单位,i从1开始。数据之间会相对稀疏。

H=(Hash0+i^2)%m ,i=1,2,3……

上述例子的过程如下:

插入11,发现冲突,第一次探测先加1^2,第二次探测加2^2,发现了空位置直接放入即可

②开散列--链地址法(哈希桶)

开散列法又称为链地址法,当发生哈希冲突时,将相同地址的值归于同一个子集合每一个子集合称为一个桶,这个桶里面的元素采用链表的方式链接起来。即每一个桶存放的都是冲突的数据!

还是以上述例子举例。插入元素11,发生冲突,采用开散列的方式,无需向后寻找空位置,直接采用头插法。。

问题:哈希表何时扩容?

这里就需要引入负载因子的说法:负载因子\alpha=有效数据个数 / 散列表长度。

从上述公式可以看出:当数据个数越多,负载因子越高,冲突率越高,效率就越低;当长度越长,负载因子越低,冲突率越低,效率就越高,但此时空间利用率就越低。

哈希表的平均查找长度是负载因子\alpha的函数,即每个元素比较次数总和 / 元素总个数

  • 对于闭散列来说,一般严格将负载因子控制在0.7-0.8之间。超过0.8查表时,cpu缓存不命中按照指数曲线上升。因此采用闭散列的方式,保险起见超过0.7就需要扩容操作
  • 对于开散列来说,最好的情况是每个哈希桶中刚好挂一个节点,再继续插入元素时,每一次都会发生哈希冲突,因此,在元素个数刚好等于桶的个数(散列表长度)时,即负载因子等于1时,就可以给哈希表增容

具体如何扩容,请看下一回实现部分,因为看到这里,您也累了,休息一下咯!


好了,老铁今天的分享内容就到这里,觉得对你有帮助,欢迎点赞+关注!

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

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

相关文章

【河北航空-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

css的“id选择器“命名问题

项目场景&#xff1a; 工程里面&#xff0c;使用到了CSS的”id选择器"&#xff0c;想让某个p标签的元素发生改变 问题描述 为什么每个p标签的元素&#xff0c;都发生了改变 <!DOCTYPE html> <html lang"en"><head><meta charset"U…

mqtt的理解

1、emqx各个端口 1883是emqx服务端的监听端口&#xff0c;通俗的讲就是emqx服务端会一直监听有哪个客户端想要连接我&#xff0c;比如springboot的MqttClient类中设置了host "tcp://192.168.1.1:1883"&#xff0c;该springboot程序作为客户端要连接到emqx服务端&am…

20.神经网络 - 搭建小实战和 Sequential 的使用

神经网络 - 搭建小实战和 Sequential 的使用 在 PyTorch 中&#xff0c;Sequential 是一个容器&#xff08;container&#xff09;类&#xff0c;用于构建神经网络模型。它允许你按顺序&#xff08;sequential&#xff09;添加不同的网络层&#xff0c;并将它们串联在一起&…

【滑动窗口法解决子数组,子串问题】

前言 在leetCode题解中看到一位大佬针对滑动窗口法解决子数组&#xff0c;子串问题的总结&#xff0c;觉得总结的非常好&#xff0c;成功地将滑动窗口法变成了默写题&#xff0c;在这里学习记录一下。 适用于 76.最小覆盖子串 567.字符串的排列 438.找到字符串中所有字母异位词…

c++习题27-大整数减法

目录 一&#xff0c;题目 二&#xff0c;思路 三&#xff0c;代码 一&#xff0c;题目 输入 共2行&#xff0c;第1行是被减数a&#xff0c;第2行是减数b(a > b)。每个大整数不超过200位&#xff0c;不会有多余的前导零。 输出 一行&#xff0c;即所求的差。 样例输入1…

SpringBoot项目路由信息自动化提取脚本

文章目录 前言工具开发1.1 ChatGPT初探1.2 初版代码效果 WebGoat适配2.1 识别常量路由2.2 适配跨行定义 进阶功能优化3.1 识别请求类型3.2 识别上下文值 总结 前言 最近工作上遇到一个需求&#xff1a;提取 SpringBoot 项目中的所有路由信息&#xff0c;本来想着这是一个再普通…

【随笔】使用spring AI接入大语言模型

引言 随着人工智能的发展&#xff0c;越来越多的应用开始集成AI模型来增强用户体验。OpenAI提供的大语言模型是目前最受欢迎的自然语言处理模型之一&#xff0c;能够处理各种语言任务&#xff0c;如文本生成、对话理解等。在Java开发中&#xff0c;我们可以利用Spring AI框架轻…

android 离线的方式使用下载到本地的gradle

1、android studio在下载gradle的时候&#xff0c;特别慢&#xff0c;有的时候会下载不完的情况&#xff0c;这样我们就要离线使用了。 2、下载Gradle Gradle | Releases 或者 Releases gradle/gradle GitHub Gradle | Releases 这里我们下载8.10 complete版本&#xff0c…

Python GraphQL 库之graphene使用详解

概要 随着 Web 技术的发展,GraphQL 已成为 REST 的一种强有力替代方案,为客户端提供了更灵活的数据查询方式。Graphene 是一个用于构建 GraphQL API 的 Python 库,它使得开发者可以轻松地将复杂的数据模型暴露为 GraphQL API。通过 Graphene,开发者可以利用 Python 的面向…

【战略游戏】

题目 代码 #include <bits/stdc.h> using namespace std; const int N 1510, M N; int h[N], e[M], ne[M], idx; int f[N][2]; int n; bool st[N]; int root; void add(int a, int b) // 添加一条边a->b {e[idx] b, ne[idx] h[a], h[a] idx ; } void dfs(int …

Java设计模式之外观模式详细讲解和案例示范

1. 引言 在软件开发过程中&#xff0c;复杂的系统往往包含许多子系统和模块&#xff0c;随着系统功能的增加&#xff0c;模块之间的交互也变得更加复杂。这种复杂性可能会导致系统的可维护性和扩展性降低。外观模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式…

【鸿蒙学习】HarmonyOS应用开发者高级认证 - 认证通过(附题目)

学完时间&#xff1a;2024年8月29日 学完排名&#xff1a;第192546名 一、前言叨叨 经过几日的休整&#xff0c;我终于再次挑战高级认证&#xff0c;并以82分的成绩堪堪越过了及格线。然而&#xff0c;通过考试后我惊讶地发现&#xff0c;原来顺利过关的人数如此众多。我逐一…

cv2图像总结

我今天发现cv2读进来的图像是BRG格式的&#xff0c;和其他的方式不同 import cv2 import matplotlib.pyplot as plt image_path "./GSE240429_data/image/GEX_C73_A1_Merged.tiff" img1 cv2.imread(image_path) print(img1.shape) plt.imshow(img1, cmapgray) …

MariaDB VS MySQL

MariaDB和MySQL是两种流行的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它们在功能、性能、兼容性、开源性以及社区支持等方面各有特点。以下是对两者主要区别的详细分析&#xff1a; 1. 开发者与起源 MySQL&#xff1a;自1995年问世以来&#xff0c…

白银现货的两大指标,如何使用?

在白银现货交易的过程中&#xff0c;我们会借助大量的技术指标&#xff0c;对现货白银走势进行分析&#xff0c;找到买点和卖点&#xff0c;可以说&#xff0c;技术指标对我们的白银现货交易起到很好的辅助作用&#xff0c;也是我们阅读白银市场很好的工具。本文将和大家讨论一…

一个非常实用的Win系统瘦身项目,PowerShell脚本支持Windows 11跟10,非常轻量好用(附源码)

Win经常我们都经常用&#xff0c;但系统里总是预装了一些我们可能并不需要的应用程序。这些应用不仅占用了宝贵的存储空间&#xff0c;还可能拖慢了我们的电脑速度。特别是Windows 11&#xff0c;一些花里胡哨的功能和后台服务&#xff0c;让我们的电脑变得不那么“清爽”。 今…

N10 - NLP中的注意力机制

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目录 1. 注意力机制是什么2. 注意力实现步骤0. 准备隐藏状态1. 获取每个编码器隐藏状态的分数2. 通过softmax层运行所有分数3. 通过softmax得分将每个编码器的…

elasticsearch之我不会的

elasticsearch之我不会的 如何安装&#xff0c;在此不谈&#xff0c;开门见山 1.概念理解 Relational DBelasticsearch说明表tableindex索引(index)&#xff0c;就是文档的集合&#xff0c;类似数据库的表(table)行rows文档documents文档&#xff08;Document&#xff09;&a…

51.x86游戏实战-XXX返回城镇的实现

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…