当前位置: 首页 > news >正文

C++简单实现哈希查找

C++ 简单实现哈希查找

1. 哈希冲突

哈希表中可能会出现哈希冲突,即多个数据项映射到相同的桶。

常见的冲突解决方法包括链地址法(Chaining)和线性探测法(Linear Probing)。

  • 使用链地址法时,每个桶维护一个链表,哈希冲突的数据项被插入到链表中。查找时,遍历链表以查找目标数据项。
  • 使用线性探测法时,如果一个桶已经被占用,算法会线性地探测下一个可用的桶,直到找到目标数据项或空桶。这种方法需要特别处理删除操作。

2. 算法执行过程

  • 初始化哈希表:创建一个固定大小的数组,将每个元素的值设置为其索引。
  • 插入元素:根据要插入的元素计算其哈希值,然后将该元素插入到对应索引的位置。如果发生哈希冲突(即两个不同的元素具有相同的哈希值),则在相应索引位置存储一个链表,链表中存储具有相同哈希值的所有元素。
  • 查找元素:首先计算要查找元素的哈希值,然后根据哈希值找到对应的索引位置。如果该位置没有其他元素,说明找到了目标元素;否则,在对应索引位置的链表中继续查找。
  • 删除元素:如果要删除的元素恰好等于目标元素,那么直接删除即可;否则,需要找到该元素所在的链表,并从链表中删除该元素。
  • 扩容:当哈希表的大小超过了数组的最大容量时,需要对数组进行扩容,即创建一个新的更大的数组,并将原数组中的元素重新插入到新数组中。同时,还需要重新计算所有元素的哈希值,并将它们插入到新数组的相应位置。****

3. 例题

例题:

有序表 A[20] = {4,6,12,20,28,38,50,70,88,100},使用哈希查找算法找出元素 20

4. 步骤

为了使用哈希查找方法实现有序表A[20]:

  • 我们需要首先定义哈希表的大小。哈希表的大小通常比表中元素的最大值要大,以确保所有元素都能被存储,并且有足够的空间来解决哈希冲突。
  • 接下来,我们需要定义一个哈希函数。一个简单的哈希函数可以是将元素值除以哈希表大小,然后取整数部分。
  • 在这个例子中,我们的哈希表大小为10,所以哈希函数可以是 h(x) = x % 10。对于整数,这个函数将把每个元素映射到一个在0到9之间的位置。
  • 现在,我们可以开始将元素插入哈希表中。由于我们使用线性探索来解决冲突,当冲突发生时,我们将在哈希表中的当前位置开始线性搜索,直到找到一个空位置为止。

以下是插入过程的步骤:

  1. 初始化哈希表:hashTable[10] = {NULL},其中 NULL 表示空位置。
  2. 对于表A中的每个元素x:
    • 计算哈希值:h(x) = x % 10
    • 确定哈希位置:index = h(x)
    • 如果 hashTable[index]NULL,则将x插入到 hashTable[pos]
    • 如果 hashTable[index]不为 NULL,则进行线性探索,寻找空位置。线性探索可以从 index + 1 开始,直到找到空位置。
  3. 重复步骤2,直到表A中的所有元素都被插入到哈希表中。
    下面是具体的插入过程:
  • 对于4,h(4) = 4 % 10 = 4, hashTable[4] 为空,插入。
  • 对于20,h(20) = 12 % 10 = 0hashTable[0] 为空,插入。
  • 对于50,h(50) = 50 % 10 = 0,但 hashTable[0] 已被占用,进行线性探索,hashTable[1] 为空,插入。
  • 依此类推,直到所有元素都被插入到哈希表中。

最终的哈希表 hashTable 将包含有序表 A 的元素,可能有一些位置为 NULL,表示在插入过程中没有发生冲突。

为了查找表中的一个元素x,我们同样使用哈希函数计算其哈希值,然后在哈希表中定位该值。

如果在定位的位置找到了元素 x,则查找成功;如果找到了 NULL,则说明元素 x 不在表中。

需要注意的是,线性探索虽然简单,但在高负载情况下(即哈希表的装载因子较高)会导致性能下降,因为可能会出现较长的查找链。

在实际应用中,可能会采用更复杂的哈希函数和冲突解决策略来提高效率。

5. 代码

#include <iostream>
#include <vector>using namespace std;// 哈希表的大小
const int HASH_TABLE_SIZE = 10;
// 哈希表
vector<int> hashTable(HASH_TABLE_SIZE, 0);  // 初始化为NULL
// 哈希函数
int hashFunction(int key) {return key % HASH_TABLE_SIZE;
}
// 线性探查
int linearProbing(int key) {int index = hashFunction(key);while (hashTable[index] != 0 && hashTable[index] != key) {index = (index + 1) % HASH_TABLE_SIZE;  // 线性探查}return index;
}// 插入键值对
void insert(int key) {int index = linearProbing(key);if (hashTable[index] == 0) {hashTable[index] = key;} else {cout << "冲突发生,键 " << key << " 已存在。" << endl;}
}// 查找键
int search(int key) {int index = hashFunction(key);while (hashTable[index] != 0) {if (hashTable[index] == key) {return index;}index = (index + 1) % HASH_TABLE_SIZE;  // 线性探查}return -1;  // 未找到键
}int main() {// 初始化有序表int A[10] = {4, 6, 12, 20, 28, 38, 50, 70, 88, 100};// 插入元素for (int i = 0; i < 10; ++i) {insert(A[i]);}for (int i = 0; i < 10; ++i) {cout << hashTable[i] << " ";}cout << endl;// 搜索元素int keyToSearch = 20;int index = search(keyToSearch);if (index != -1) {cout << "键 " << keyToSearch << " 在哈希表中的位置是: " << index << endl;} else {cout << "键 " << keyToSearch << " 在哈希表中未找到。" << endl;}return 0;
}

6. 使用场景

  1. 字典和关联数组:哈希表常用于实现字典和关联数组,其中键映射到值。这样可以快速查找特定键对应的值。
  2. 缓存:哈希表用于数据缓存,允许快速访问已经检索的数据,以减少对慢速存储介质(如磁盘)的访问。
  3. 数据库索引:在数据库管理系统中,哈希表用于构建索引,以便快速检索和访问数据库中的数据。这在大型数据库中非常有用。
  4. 散列集合:编程语言中的集合(Set)和散列集合(HashSet)通常使用哈希表来实现,以便快速查找成员。
  5. 数据去重:哈希表可用于检测和删除重复数据项。通过将数据插入哈希表并检查是否已经存在,可以有效去重。
  6. 认证和授权:哈希表可用于存储用户凭据(如用户名和密码)或授权令牌,以便快速验证用户身份。
  7. 编译器符号表:编程语言编译器使用哈希表来管理符号表,以便快速查找变量、函数和其他符号的定义和引用。
  8. 数据分布:在分布式计算中,哈希表用于确定数据项应该存储在哪个节点或分片,以实现均匀的数据分布。
  9. 缓存管理:缓存管理系统通常使用哈希表来跟踪缓存的内容,以加速数据检索。
  10. 路由表:网络路由器使用哈希表来管理路由表,以确定数据包的转发路径。
  11. 文件系统索引:文件系统通常使用哈希表来维护文件索引,以加速文件查找和访问。
  12. 编码查找表:在编码和解码中,哈希表可用于存储查找表,以实现快速的字符或编码查找。

相关文章:

C++简单实现哈希查找

C 简单实现哈希查找 1. 哈希冲突 哈希表中可能会出现哈希冲突&#xff0c;即多个数据项映射到相同的桶。 常见的冲突解决方法包括链地址法&#xff08;Chaining&#xff09;和线性探测法&#xff08;Linear Probing&#xff09;。 使用链地址法时&#xff0c;每个桶维护一个链…...

计算机网络简答题:复试+期末

文章目录 1.计算机网络的功能:2.计算机网络的分类:3.主机间的通信方式:4.电报交换、报文交换、分组交换的区别:5.计算机网络的性能指标:6.0SI模型和TCP/IP模型:7.通信信通的方式:8.端到端的通信与点到点通信的区别:9.同步通信和异步通信:10.频分复用、时分复用、波分复用和码分…...

若依ruoyi-vue中的文件上传和下载

文章目录 文件上传后端实现前端实现 文件下载后端实现前端实现 在若依&#xff08;Ruoyi&#xff09;框架中&#xff0c;结合 Vue 前端框架&#xff0c;文件的上传和下载通常使用以下方法实现&#xff1a; 文件上传 若依现成的功能里面没有文件上传&#xff0c;但是集成了文件…...

链表oj测试题(上)

链表的申明&#xff1a; struct ListNode {int val;struct ListNode* next; }; 1.题1 删除指定元素 例如&#xff1a;链表1 2 6 3 4 5 6&#xff0c;然后选择删除元素6&#xff0c;返回的链表为1 2 3 4 5 。 代码演示&#xff1a; typedef struct ListNode ListNode;List…...

鸿蒙APP应用开发教程—超详细的项目结构说明

1. 新建项目 打开DevEco Studio, 选择 Create Project: 1.1 选择模版 Create Project - Choose Template 1.2 配置项目 Create Project - Configure Project 如果使用的是 DevEco 3.X 版本, 可以根据 Compile SDK版本选择不同的模式, 比如: 3.0.0(API 8)及更早 - 仅支持 …...

C语言经典算法-7

文章目录 其他经典例题跳转链接36.排序法 - 改良的选择排序37.快速排序法&#xff08;一&#xff09;38.快速排序法&#xff08;二&#xff09;39.快速排序法&#xff08;三&#xff09;40.合并排序法 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三…...

设计模式(结构型设计模式——桥接模式)

设计模式&#xff08;结构型设计模式——桥接模式&#xff09; 桥接模式 基本定义 桥接模式将继承关系转化成关联关系&#xff0c;它降低了类与类之间的耦合度&#xff0c;减少了系统中类的数量&#xff0c;也减少了代码量。 降低了类与类之间的耦合度&#xff1a;脱耦就是将…...

Java的三大特性之一——继承

前言 http://t.csdnimg.cn/uibg3 在上一篇中我们已经讲解过封装&#xff0c;这里就主要讲解继承与多态 继承 1.为什么需要继承 Java中使用类对现实世界中实体来进行描述&#xff0c;类经过实例化之后的产物对象&#xff0c;则可以用来表示现实中的实体&#xff0c;但是现实…...

Java复习05 Spring 概念

Java复习05 Spring 概念 初学 Spring 的时候 我的问题是 什么是Spring&#xff1f; Spring的底层实现是什么&#xff1f;为什么现在Java都在用sping框架&#xff1f; 1.把Spring类比成乐高说明书 想象一下你有一个超级大的乐高积木盒子&#xff0c;里面有各种各样的积木。你…...

初级爬虫实战——哥伦比亚大学新闻

文章目录 发现宝藏一、 目标二、简单分析网页1. 寻找所有新闻2. 分析模块、版面和文章 三、爬取新闻1. 爬取模块2. 爬取版面3. 爬取文章 四、完整代码五、效果展示 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不…...

【JS】深度学习JavaScript

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【JS】深度学习JavaScript &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 一:JavaScript1.1 JavaScript是什么1.2 JS的引入方式1.3 JS变量1.4 数据类型1.5 …...

云原生相关知识

一、kubernetes 1 概述 Kubernetes&#xff08;也称 k8s 或 “kube”&#xff09;是一 个​​开源​​的容器编排平台&#xff0c;可以自动完成在部署、管理和扩展容器化应用过程中涉及的许多手动操作。 我们常说的编排的英文单词为 “Orchestration”&#xff0c;它常被解释…...

【多线程】有了解过 CAS 和原子操作吗?

SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;学习Java 个性签名&#xff1a;人生乏味啊&#xff0c;我欲令之光怪陆离 本文封面由 凯楠&#x1f4f7; 友情赞助! 目录 前言 悲观锁和乐观锁 什么是 CAS ? 什么是原子操作&#xff1f; CAS 执行流…...

Linux 服务升级:Nginx 热升级 与 平滑回退

目录 一、实验 1.环境 2.Kali Linux 使用nmap扫描CentOS 3.Kali Linux 远程CentOS 4.Kali Linux 使用openvas 扫描 CentOS 5.Nginx 热升级 6.Nginx 平滑回退 二、问题 1.kill命令的信号有哪些 2.平滑升级与回退的信号 一、实验 1.环境 &#xff08;1&#xff09;主机…...

能降低嵌入式系统功耗的三个技术

为电池寿命设计嵌入式系统已经成为许多团队重要的设计考虑因素。优化电池寿命的能力有助于降低现场维护成本&#xff0c;并确保客户不需要不断更换或充电电池&#xff0c;从而获得良好的产品体验。 团队通常使用一些标准技术来提高电池寿命&#xff0c;例如将处理器置于低功耗…...

暴力快速入门强化学习

强化学习算法的基本思想&#xff08;直觉&#xff09; 众所周知&#xff0c;强化学习是能让智能体实现某个具体任务的强大算法。 强化学习的基本思想是让智能体跟环境交互&#xff0c;通过环境的反馈让智能体调整自己的策略&#xff0c;从反馈中学习&#xff0c;不断学习来得到…...

vue中v-if和v-show的区别

手段&#xff1a;v-if是动态的向DOM树内添加或者删除DOM元素&#xff1b;v-show是通过设置DOM元素的display样式属性控制显隐&#xff1b;编译过程&#xff1a;v-if切换有一个局部编译/卸载的过程&#xff0c;切换过程中合适地销毁和重建内部的事件监听和子组件&#xff1b;v-s…...

MATLAB绘图

现学现用&#xff0c;用时再学。 plot函数:有两个向量被指定为参数&#xff0c;plot(x,y) 会生成 y 对 x 的图形 添加轴标签和标题: 通过调用一次 plot&#xff0c;多个 x-y 对组参数会创建多幅图形: 在每十个数据点处放置标记: 一个窗口绘制多个图形; 可在弹窗的插入选项上添加…...

嵌入式学习-ARM-Day4

嵌入式学习-ARM-Day4 实现三个LED灯亮灭 .text .global _start _start: 使能GPIOE的外设时钟 RCC_MP_AHB4ENSETR的第[4]设置为1即可使能GPIOE时钟 LED1 LDR R0,0X50000A28 指定寄存器地址 LDR R1,[R0] 将寄存器原来的数值读取出来&#xff0c;保存到R1中 ORR R1,R1,#(0x…...

MySQL 中的事务和存储引擎

目录 事务的 ACID 特性 MySQL 的四种隔离机制和问题 MySQL 的四种隔离机制&#xff1a; MySQL 的存储引擎 InnoDB 存储引擎 MyISAM 存储引擎 Memory 存储引擎 通过 ALTER TABLE 语句更改存储引擎 在创建表时指定存储引擎 通过修改配置文件设置默认存储引擎 在数据库系…...

DeepSeek系统设计辅助:如何在48小时内完成可审计、可回滚、可压测的AI服务架构图?

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;DeepSeek系统设计辅助 DeepSeek系统设计辅助模块面向架构师与后端工程师&#xff0c;提供模型能力调用、接口契约生成、异步任务编排等核心支撑能力。该模块不替代人工设计决策&#xff0c;而是通过结构…...

AArch64内存管理:MAIR_EL3寄存器详解与应用

1. AArch64内存管理基础与MAIR_EL3寄存器定位 在Armv8-A/v9-A架构中&#xff0c;内存管理单元(MMU)通过多级页表实现虚拟地址到物理地址的转换。当处理器执行内存访问时&#xff0c;MMU会遍历页表条目(Translation Table Entry)&#xff0c;其中包含两个关键信息&#xff1a;目…...

服务器日志分析实战:用Python追踪HTTP 404错误并可视化异常频率

作为一名爬虫开发者或网站运维人员,服务器日志就像飞机的“黑匣子”——它记录了每个请求的来龙去脉。而404错误(页面未找到)尤其值得关注:它可能是用户输错了网址,可能是你爬虫的URL构造逻辑有漏洞,也可能是网站改版后旧的链接失效了。更严重的是,大量突然涌出的404请求…...

Vue3 图片标框功能实现方案

基于 Vue3 组合式 API 的图片标框&#xff08;画框、标注、选框&#xff09;完整实现&#xff0c;核心逻辑封装在 GetBoxes 组件里&#xff0c;复制就能用 一、功能说明 ✅ 在图片上鼠标拖拽画矩形框 ✅ 实时显示框坐标&#xff08;x, y, width, height&#xff09; ✅ 支持多…...

taotoken如何帮助ubuntu开发者应对大模型api的频繁更新与版本迭代

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Taotoken如何帮助Ubuntu开发者应对大模型API的频繁更新与版本迭代 对于在Ubuntu环境下进行开发的工程师而言&#xff0c;大模型API…...

Elden Ring帧率解锁终极指南:从60帧到144+的完整教程

Elden Ring帧率解锁终极指南&#xff1a;从60帧到144的完整教程 【免费下载链接】EldenRingFpsUnlockAndMore A small utility to remove frame rate limit, change FOV, add widescreen support and more for Elden Ring 项目地址: https://gitcode.com/gh_mirrors/el/Elden…...

别再只比参数了!从插件生态到中文优化,聊聊ChatGPT和文心一言的“隐形”差异

超越参数之争&#xff1a;ChatGPT与文心一言的生态与本土化实战解析 当技术评测文章还在反复比较模型参数量与发布时间时&#xff0c;真正影响日常工作效率的往往是那些未被量化的"软实力"。本文将从插件生态构建与中文场景优化两个维度&#xff0c;带您重新认识这两…...

猫抓浏览器扩展终极指南:5分钟掌握全网视频资源下载技巧

猫抓浏览器扩展终极指南&#xff1a;5分钟掌握全网视频资源下载技巧 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你是否经常遇到心仪的视频无法…...

避坑指南:Unity动态加载模型时,TriLib插件材质丢失、缩放异常的5个常见问题解决

Unity动态加载模型避坑指南&#xff1a;TriLib插件材质丢失与缩放异常的深度解决方案当你在Unity项目中尝试使用TriLib插件动态加载外部模型时&#xff0c;是否遇到过这些令人抓狂的情况&#xff1a;模型加载后材质全部变成刺眼的粉红色&#xff0c;贴图神秘消失&#xff0c;或…...

红外信号逆向工程:破解电磁炉协议实现抽油烟机智能联动

1. 项目概述&#xff1a;当电磁炉与抽油烟机“对话”厨房里的自动化&#xff0c;听起来像是未来智能家居的专属&#xff0c;但其实很多乐趣和便利就藏在身边已有的设备里。我最近给家里的厨房换上了一台新的电磁炉&#xff0c;在翻阅说明书时&#xff0c;偶然发现了一个名为“h…...