【基础算法】哈希表(拉链法)
🌹作者:云小逸
📝个人主页:云小逸的主页
📝Github:云小逸的Github
🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前,其次就是现在!学会自己和解,与过去和解,努力爱自己。==希望春天来之前,我们一起面朝大海,春暖花开!==🤟
👏专栏:C++👏 👏专栏:Java语言👏👏专栏:Linux学习👏
👏专栏:C语言初阶👏👏专栏:数据结构👏👏专栏:备战蓝桥杯👏
文章目录
- 前言
-
- 哈希表:
- 哈希表的含义:
- 哈希表的作用:
- 哈希表的思想:
- 1.映射
- 2.冲突:
- 例题:
- 题目:
- 输入格式
- 输出格式
- 数据范围
- 输入样例:
- 输出样例:
- 拉链法:
- 1.先将原数组值域映射到哈希函数:
- 2.建立一个槽,将映射的结果链接到槽上
- 3.取模的N要为质数,且尽可能地离2的整数次幂尽可能的远。
- 代码:
- 代码解析:
-
- 最后
-
-
前言
今天我们来学习一下新知识【哈希表】,这个是算法中比较重要的知识点,希望下面我的讲解你可以喜欢。如果有错误,请私信告知,望见谅。
——————————————————————————————————————————
首先先写上几句话:献给坚持创作的我和点开这篇文章希望进步的你
1.很喜欢《稻盛和夫对年轻人的忠告》里这段话:“大部分人对吃苦的含义了解得太浅了。吃苦不是穷,而是一个人长时间为了某个目标而聚焦的能力。在这个过程中,放弃娱乐生活,放弃无效社交,放弃无意义的消费以及在此过程中不被理解的孤独。”它本质是一种自控力,自制力,坚持和深度思考的能力。
2.以前我被误解的时候,我总会想去解释,你误会我了,我不是这样的人,我会想尽一切办法去证明自己。而现在,对于别人的误解,我不在乎也不想去辩解,我信任的人误会我,我会觉得挺好的,原来我在你心里是这样的人。
鱼那么相信水,水却煮了鱼;叶子那么信任风,风却吹落了叶;在自己的世界里独善其身,取悦自己,在别人的世界里顺其自然。
3.看到过这样一段话:“我希望你努力,不是为了要跟别人比成绩,而是因为,我希望你将来拥有选择的权利,选择有意义的生活,而不是被迫谋生。
当我们努力之后,我们才有机会不拘泥于方寸之地,不用只过着毫无新意、一眼望到头、没任何期待的日子。拥有选择权,我们才有底气和实力去选择我们想要的生活。
哈希表:
哈希表的含义:

上面是百度百科的说法;
散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存储存位置的数据结构。也就是说,它通过计算出一个键值的函数,将所需查询的数据映射到表中一个位置来让人访问,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。
这是维基百科的解释,
一个通俗的例子是,为了查找电话簿中某人的号码,可以创建一个按照人名首字母顺序排列的表〈和建立人名z到首字母F(赏)的一个函数关系),在首字母为W的表中查找“王”姓的电话号码,显然比宜直接查找就要快得多。这里使用人名作为关键字,“取首字母”是这个例子中散列函数的函数法则F(),存放首字母的表对应荀列表。关键字和函数法则理论上可以任意确定.
两者在对于哈希表的解释都不约而同的说了两点:码值和映射。

下面借助百度百科的这张图便于你的理解:
先建立一个哈希函数(设定一个范围),再将不同的数分别映射到哈希函数上。
哈希表的作用:
把一个复杂的数据结构(值域,数据)映射到[0,n];
n一般是10的五次方或者10的六次方
如将[0,109]映射到[0,105]
哈希表的思想:
1.映射
将一段较大的数组映射到一段相对较小的数组,当要查找一个元素的时候,可以根据这个元素所映射对应的位置进行直接查找,而不是遍历查找,这样就可以更加高效的完成查找功能。
注:哈希一般常用的是增加和查找功能,如果想要删除一个数据,也不是真正意义上的删除,而是设定一个布尔数值,布尔值为false时代表删除这个数据。
2.冲突:
我们可以从这个图上的得知:多个数据可能会映射到同一个数值的情况。

针对这个情况,处理冲突有多重方法,如:
1.拉链法:
2.开放寻址法
3.再散列法
4.建立一个公共溢出区
这里详细介绍一下:拉链法和开放寻址法
例题:
题目:
维护一个集合,支持如下几种操作:
I x,插入一个数 x;
Q x,询问数 x 是否在集合中出现过;
现在要进行 N 次操作,对于每个询问操作输出对应的结果。
输入格式
第一行包含整数 N,表示操作数量。接下来 N 行,每行包含一个操作指令,操作指令为 I x,Q x 中的一种。
输出格式
对于每个询问指令 Q x,输出一个询问结果,如果 x 在集合中出现过,则输出 Yes,否则输出 No。
每个结果占一行。
数据范围
1≤N≤105
−109≤x≤109
输入样例:
5
I 1
I 2
I 3
Q 2
Q 5
输出样例:
Yes
No
拉链法:
1.先将原数组值域映射到哈希函数:
如果值域为[-109,109],将其映射到[0,105]
则 x mod105 (mod是取模)这样就可以使其范围在[0,105],
上面的数值都是假设便于你的理解。
真正的代码应该是这样的:
int k = (x % N + N) % N;
这个代码的意思是将x取余将x映射到[0,N]范围内。
因为在C++中如果负数取模后仍然是负数,因此需要先取模后加上N再对N取模其结果一定是一个正数。
2.建立一个槽,将映射的结果链接到槽上

如上图所示,假设11的映射为3,23的映射也是3,将11链接槽上的3,将23链接在11后面,这个使用的是链表的结构存储拉链。
3.取模的N要为质数,且尽可能地离2的整数次幂尽可能的远。

这样的取N冲突的概率是最小的。
代码:
#include <cstring>
#include <iostream>using namespace std;const int N = 100003;//这里可以自己写一个求大于100000第一个质数的代码求出即可int h[N];//这是上面说的开一个槽
int e[N], ne[N], idx;//与槽链接的拉链,用链表存储,//e[N]用来存值,ne[N]下一个的位置,idx表示当前移动到哪一个位置void insert(int x)
{int k = (x % N + N) % N;//k是哈希值e[idx] = x;ne[idx] = h[k];h[k] = idx ++ ;//插入操作,类似于头插
}bool find(int x)
{int k = (x % N + N) % N;for (int i = h[k]; i != -1; i = ne[i])if (e[i] == x)return true;return false;
}int main()
{int n;scanf("%d", &n);memset(h, -1, sizeof h);//将槽清空,空指针一般用-1来表示while (n -- ){char op[2];int x;scanf("%s%d", op, &x);if (*op == 'I') insert(x);else{if (find(x)) puts("Yes");else puts("No");}}return 0;
}
代码解析:
const int N = 100003;//这里可以自己写一个求大于100000第一个质数的代码求出即可int h[N];//这是上面说的开一个槽
int e[N], ne[N], idx;//与槽链接的拉链,用链表存储,//e[N]用来存值,ne[N]下一个的位置,idx表示当前移动到哪一个位置

这里存一个字符用的是字符数组,读入字符串,而不是直接的一个字符进行存储,因为将其以一个字符串进行读入,这样scanf可以自动忽略掉空格和回车,这样可以降低出错概率。
void insert(int x)
{int k = (x % N + N) % N;//k是哈希值e[idx] = x;ne[idx] = h[k];h[k] = idx ++ ;//插入操作,类似于头插
}
这个是插入操作,类似于链表的头插。
下面做一个动图,便于你的理解:

最后
十分感谢你可以耐着性子把它读完和我可以坚持写到这里,送几句话,对你,也对我:
1.这些年来一直在提醒自己一件事,千万不要感动自己,大部分人看似努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几个小时,多久没放假了。如果这些东西也值得炫耀,那么富士康流水线上任何一个人都比你努力多了。
人难免天生有自怜情绪,唯有时刻保持清醒,才看得清真正的价值在哪里。
2.这一生中有许多的人朝我走来,然后又匆匆忙忙的消失在人山人海中,那些人与我短暂交错,尾声潮落。从开始的不舍到最后的习以为常,便明白这是人生常态。真心待人,开始不再执着任何一段关系,即使是阶段性的陪伴,在相处的过程中我们开心就好,就活在当下。
海阔凭鱼跃,天高任鸟飞,路要朝前走,人要往前看。山林不向四季起誓,枯荣随缘,海洋不需对沙岸许诺,遇合尽兴。
3.见了太多糟糕的事情,反倒觉得一切都会好起来。心情不好就听歌,饿了就找吃的,怕黑就开灯,喜欢的东西就赚钱买。
有人紧握你的手就可能会松开,有人给你承诺也会有失言的时候,长大后才发现真正想要的东西总归要自己争取,只有自己才不会辜负自己。
顺其自然真的是我对当下的生活态度了,人就应该活在当下,把今天过得很积极明天一定不会太差。别想太多,好好生活,也许日子过着过着就有答案了。
最后如果觉得我写的还不错,请不要忘记点赞✌,收藏✌,加关注✌哦(。・ω・。)
愿我们一起加油,奔向更美好的未来,愿我们从懵懵懂懂的一枚菜鸟逐渐成为大佬。加油,为自己点赞!
相关文章:
【基础算法】哈希表(拉链法)
🌹作者:云小逸 📝个人主页:云小逸的主页 📝Github:云小逸的Github 🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前…...
硬件学习 软件Cadence day07 PCB 底板电路图布线
1.根据原理图的元器件, 选择在 PCB 芯片制作的元器件 (allegro中原理图和pcb中元件的交互) 1.首先完成下列操作 可以尝试先关闭再打开, 等下操作的时候就好 发现新增的发光物体!! 2.完成操作 ,…...
SkyWalking仪表盘使用
Skywalking仪表盘使用 1 仪表盘 作用:查看被监控服务的运行状态。 1)监控面板 1.1 APM APM:应用性能管理,通过各种探针采集数据,收集关键指标,同时搭配数据呈现以实现对应用程序性能管理和故障管理的系统化解决方案…...
面渣逆袭:分布式十二问,万字图文详解
大家好,我是老三,不管今年金三银四如何,面渣逆袭系列继续,这期我们来看看分布式。 分布式理论 1. 说说CAP原则? CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性…...
设计模式C++实现23:中介者模式(Mediator)
部分内容参考大话设计模式第25章;本实验通过C语言实现。 一 原理 意图:用一个中介对象来封装一系列对象的交互,中介者使得各个对象不需要显示地相互引用,从而使耦合松散,而且可以独立地改变它们之间的交互。 上下文…...
Java方法【未完待续】
目录 前言 一、什么是方法? 二、方法的定义和调用 方法的定义 方法的调用 三、方法的重载 重载规则 实现理论 总结 前言 随着对Java这一编程语言的深入学习,大家可能会遇到一个熟悉又陌生的词——方法,其实Java方法就是我们学习C/C时…...
(考研湖科大教书匠计算机网络)第六章应用层-第一、二节:应用层概述和C/S及P2P
获取pdf:密码7281专栏目录首页:【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一:应用层概述二:客户/服务器(C/S)和对等(P2P)方式(1)客户/服务器&…...
禅道bug提醒脚本部署
环境准备 nginxpython3 服务器目录 以下目录为自定义配置,需在 nginx 默认配置文件的http{}内添加 include /www/conf/*.conf; 才会生效 /www ├── conf "存放配置文件 │ └── lowCode.zyl.conf "低代码bug统计页配置 ├── wwwlogs "存…...
利用spring的retry重试编写Feign远程调用重试
自定义注解FeignRetry为了解决上面提到的问题,让Feign调用的每个接口单独配置不同的重试机制。我们使用了面向切面编程并编写了一个自定义注解:FeignRetry。此注释的工作方式类似于Retryable的包装器,并与其共享相同的规范以避免混淆。Target…...
Docker启动RabbitMQ,实现生产者与消费者
目录 一、Docker拉取镜像并启动RabbitMQ 二、Hello World (一)依赖导入 (二)消息生产者 (三)消息消费者 三、实现轮训分发消息 (一)抽取工具类 (二)启…...
【C语言】函数栈帧的创建与销毁
Yan-英杰的主页 悟已往之不谏 知来者之可追 目录 0.ebp和esp是如何来维护栈帧的呢? 1.为什么局部变量的值不初始化是随机的? 2.局部变量是怎么创建的? 3 .函数是如何传参的?传参的顺序是怎样的 4.函数是如何调用的 …...
【Git】使用Git上传项目到远程仓库Gitee码云步骤详解
电脑里存放了很多项目,有的备份,有的没备份,如果不仔细分类管理的话,时间一长,到时看到那就会觉得非常杂乱,很难整理,这里有一个叫源代码托管,用过它的都知道,方便管理和…...
Head First设计模式---3.装饰者模式
3.1装饰者模式 亦称: 装饰者模式、装饰器模式、Wrapper、Decorator 装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 举个例子:天气很冷,我们一件一件穿衣服,…...
Python 算法交易实验48 表字段设计
说明 虽然说的是表,实际上用的是Mongo集合 基于ADBS(APIFunc DataBase Service)可以构造一个供后续研究、生产长时间使用的数据基础,这个基础包括了: 1 队列服务。通过队列,数据可以通过API实现零担和批量两种模式的快速存储。2 …...
库存管理系统-课后程序(JAVA基础案例教程-黑马程序员编著-第六章-课后作业)
【案例6-1】 库存管理系统 【案例介绍】 1.任务描述 像商城和超市这样的地方,都需要有自己的库房,并且库房商品的库存变化有专人记录,这样才能保证商城和超市正常运转。 本例要求编写一个程序,模拟库存管理系统。该系统主要包…...
【极海APM32替代笔记】HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒、串口唤醒和回调无法一起使用、接收数据不全的问题)
【极海APM32替代笔记】HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒、串口唤醒和回调无法一起使用、接收数据不全的问题) 【STM32笔记】低功耗模式配置及避坑汇总 前文: blog.csdn.net/weixin_53403301/article/details/128216…...
Python类变量和实例变量(类属性和实例属性)
无论是类属性还是类方法,都无法像普通变量或者函数那样,在类的外部直接使用它们。我们可以将类看做一个独立的空间,则类属性其实就是在类体中定义的变量,类方法是在类体中定义的函数。 在类体中,根据变量定义的位置不…...
Glide加载图片
使用Glide加载图片,默认情况下在内存中缓存该图片。这样的情况下如果我们保存头像在某个路径,当再次更换头像时可能由于缓存问题,UI上更新的不及时。 默认加载图片方式: Glide.with(context).load(coverPath).error(R.drawable.a…...
有关时间复杂度和空间复杂度的练习
目录 一、消失的数字 二、轮转数组 三、 单选题 一、消失的数字 数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在 O(n) 时间内完成吗? 注意:本题相对书上原题稍作改动 示例 1: 输入…...
linux服务器nfs数据挂载
参考:https://blog.csdn.net/qq_43721935/article/details/119889841?from_wecom1 1、NFS 介绍 NFS 即网络文件系统(Network File-System),可以通过网络让不同机器、不同系统之间可以实现文件共享。通过 NFS,可以访问…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor
1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...
