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之间的位置。 - 现在,我们可以开始将元素插入哈希表中。由于我们使用线性探索来解决冲突,当冲突发生时,我们将在哈希表中的当前位置开始线性搜索,直到找到一个空位置为止。
以下是插入过程的步骤:
- 初始化哈希表:
hashTable[10] = {NULL},其中NULL表示空位置。 - 对于表A中的每个元素x:
- 计算哈希值:
h(x) = x % 10 - 确定哈希位置:
index = h(x) - 如果
hashTable[index]为NULL,则将x插入到hashTable[pos] - 如果
hashTable[index]不为NULL,则进行线性探索,寻找空位置。线性探索可以从index + 1开始,直到找到空位置。
- 计算哈希值:
- 重复步骤2,直到表A中的所有元素都被插入到哈希表中。
下面是具体的插入过程:
- 对于4,
h(4) = 4 % 10 = 4,hashTable[4]为空,插入。 - 对于20,
h(20) = 12 % 10 = 0,hashTable[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. 使用场景
- 字典和关联数组:哈希表常用于实现字典和关联数组,其中键映射到值。这样可以快速查找特定键对应的值。
- 缓存:哈希表用于数据缓存,允许快速访问已经检索的数据,以减少对慢速存储介质(如磁盘)的访问。
- 数据库索引:在数据库管理系统中,哈希表用于构建索引,以便快速检索和访问数据库中的数据。这在大型数据库中非常有用。
- 散列集合:编程语言中的集合(Set)和散列集合(HashSet)通常使用哈希表来实现,以便快速查找成员。
- 数据去重:哈希表可用于检测和删除重复数据项。通过将数据插入哈希表并检查是否已经存在,可以有效去重。
- 认证和授权:哈希表可用于存储用户凭据(如用户名和密码)或授权令牌,以便快速验证用户身份。
- 编译器符号表:编程语言编译器使用哈希表来管理符号表,以便快速查找变量、函数和其他符号的定义和引用。
- 数据分布:在分布式计算中,哈希表用于确定数据项应该存储在哪个节点或分片,以实现均匀的数据分布。
- 缓存管理:缓存管理系统通常使用哈希表来跟踪缓存的内容,以加速数据检索。
- 路由表:网络路由器使用哈希表来管理路由表,以确定数据包的转发路径。
- 文件系统索引:文件系统通常使用哈希表来维护文件索引,以加速文件查找和访问。
- 编码查找表:在编码和解码中,哈希表可用于存储查找表,以实现快速的字符或编码查找。
相关文章:
C++简单实现哈希查找
C 简单实现哈希查找 1. 哈希冲突 哈希表中可能会出现哈希冲突,即多个数据项映射到相同的桶。 常见的冲突解决方法包括链地址法(Chaining)和线性探测法(Linear Probing)。 使用链地址法时,每个桶维护一个链…...
计算机网络简答题:复试+期末
文章目录 1.计算机网络的功能:2.计算机网络的分类:3.主机间的通信方式:4.电报交换、报文交换、分组交换的区别:5.计算机网络的性能指标:6.0SI模型和TCP/IP模型:7.通信信通的方式:8.端到端的通信与点到点通信的区别:9.同步通信和异步通信:10.频分复用、时分复用、波分复用和码分…...
若依ruoyi-vue中的文件上传和下载
文章目录 文件上传后端实现前端实现 文件下载后端实现前端实现 在若依(Ruoyi)框架中,结合 Vue 前端框架,文件的上传和下载通常使用以下方法实现: 文件上传 若依现成的功能里面没有文件上传,但是集成了文件…...
链表oj测试题(上)
链表的申明: struct ListNode {int val;struct ListNode* next; }; 1.题1 删除指定元素 例如:链表1 2 6 3 4 5 6,然后选择删除元素6,返回的链表为1 2 3 4 5 。 代码演示: 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.快速排序法(一)38.快速排序法(二)39.快速排序法(三)40.合并排序法 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三…...
设计模式(结构型设计模式——桥接模式)
设计模式(结构型设计模式——桥接模式) 桥接模式 基本定义 桥接模式将继承关系转化成关联关系,它降低了类与类之间的耦合度,减少了系统中类的数量,也减少了代码量。 降低了类与类之间的耦合度:脱耦就是将…...
Java的三大特性之一——继承
前言 http://t.csdnimg.cn/uibg3 在上一篇中我们已经讲解过封装,这里就主要讲解继承与多态 继承 1.为什么需要继承 Java中使用类对现实世界中实体来进行描述,类经过实例化之后的产物对象,则可以用来表示现实中的实体,但是现实…...
Java复习05 Spring 概念
Java复习05 Spring 概念 初学 Spring 的时候 我的问题是 什么是Spring? Spring的底层实现是什么?为什么现在Java都在用sping框架? 1.把Spring类比成乐高说明书 想象一下你有一个超级大的乐高积木盒子,里面有各种各样的积木。你…...
初级爬虫实战——哥伦比亚大学新闻
文章目录 发现宝藏一、 目标二、简单分析网页1. 寻找所有新闻2. 分析模块、版面和文章 三、爬取新闻1. 爬取模块2. 爬取版面3. 爬取文章 四、完整代码五、效果展示 发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不…...
【JS】深度学习JavaScript
💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录文章:【JS】深度学习JavaScript 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 一:JavaScript1.1 JavaScript是什么1.2 JS的引入方式1.3 JS变量1.4 数据类型1.5 …...
云原生相关知识
一、kubernetes 1 概述 Kubernetes(也称 k8s 或 “kube”)是一 个开源的容器编排平台,可以自动完成在部署、管理和扩展容器化应用过程中涉及的许多手动操作。 我们常说的编排的英文单词为 “Orchestration”,它常被解释…...
【多线程】有了解过 CAS 和原子操作吗?
SueWakeup 个人主页:SueWakeup 系列专栏:学习Java 个性签名:人生乏味啊,我欲令之光怪陆离 本文封面由 凯楠📷 友情赞助! 目录 前言 悲观锁和乐观锁 什么是 CAS ? 什么是原子操作? 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.环境 (1)主机…...
能降低嵌入式系统功耗的三个技术
为电池寿命设计嵌入式系统已经成为许多团队重要的设计考虑因素。优化电池寿命的能力有助于降低现场维护成本,并确保客户不需要不断更换或充电电池,从而获得良好的产品体验。 团队通常使用一些标准技术来提高电池寿命,例如将处理器置于低功耗…...
暴力快速入门强化学习
强化学习算法的基本思想(直觉) 众所周知,强化学习是能让智能体实现某个具体任务的强大算法。 强化学习的基本思想是让智能体跟环境交互,通过环境的反馈让智能体调整自己的策略,从反馈中学习,不断学习来得到…...
vue中v-if和v-show的区别
手段:v-if是动态的向DOM树内添加或者删除DOM元素;v-show是通过设置DOM元素的display样式属性控制显隐;编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-s…...
MATLAB绘图
现学现用,用时再学。 plot函数:有两个向量被指定为参数,plot(x,y) 会生成 y 对 x 的图形 添加轴标签和标题: 通过调用一次 plot,多个 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] 将寄存器原来的数值读取出来,保存到R1中 ORR R1,R1,#(0x…...
MySQL 中的事务和存储引擎
目录 事务的 ACID 特性 MySQL 的四种隔离机制和问题 MySQL 的四种隔离机制: MySQL 的存储引擎 InnoDB 存储引擎 MyISAM 存储引擎 Memory 存储引擎 通过 ALTER TABLE 语句更改存储引擎 在创建表时指定存储引擎 通过修改配置文件设置默认存储引擎 在数据库系…...
别再手动改参数了!用MATLAB脚本一键配置Simulink模型(附.m文件模板)
MATLAB脚本自动化配置Simulink模型的工程实践 每次打开Simulink模型都要重复修改几十个模块参数?还在为版本迭代时参数同步问题头疼?电气控制系统仿真中,模型参数的统一管理和快速配置直接影响开发效率。本文将分享如何用MATLAB脚本实现Simul…...
C语言编程手机版 随时编译代码
社会持续向前发展,当下那些在进行编程学习的用户数量日益增多,然而借助电脑去学习会相对麻烦些。鉴于此,小编给大伙带来了C语言编译器手机版,它是一款功能表现非常强,操作实施较为简便的C语言编程软件,其主…...
Xinference-v1.17.1视频内容审核系统实战
Xinference-v1.17.1视频内容审核系统实战 视频内容审核一直是内容平台面临的重要挑战,传统的人工审核方式效率低下且成本高昂。今天我们来体验一下基于Xinference-v1.17.1构建的视频内容审核系统,看看AI如何智能识别违规内容。 1. 系统核心能力展示 X…...
Qwen-Image-Edit-2511在云端:集成显卡/Mac也能流畅运行的AI修图方案
Qwen-Image-Edit-2511在云端:集成显卡/Mac也能流畅运行的AI修图方案 1. 为什么选择云端部署Qwen-Image-Edit-2511? 1.1 硬件限制的突破性解决方案 传统AI图像编辑工具对硬件的高要求一直是普通用户的痛点。Qwen-Image-Edit-2511作为最新一代多模态编辑…...
OpenClaw调用Qwen3-32B镜像成本实测:RTX4090D长任务Token消耗分析
OpenClaw调用Qwen3-32B镜像成本实测:RTX4090D长任务Token消耗分析 1. 为什么关注OpenClaw的Token消耗问题 第一次用OpenClaw完成文件整理任务时,我被账单吓了一跳——短短10分钟的操作消耗了近3万Token。这让我意识到:自动化助手的长期使用…...
多人对话场景模拟:交替使用不同音色生成对话片段
多人对话场景模拟:交替使用不同音色生成对话片段 1. 引言:让AI语音对话更真实自然 想象一下这样的场景:你需要制作一段多人对话的音频内容,可能是教学演示、广播剧、或者产品介绍。传统方法需要找不同的人录音,费时费…...
Jetson Nano 平台YOLO目标检测优化详细设计方案
Jetson Nano 平台YOLO目标检测优化详细设计方案 1. 项目概况与设计目标 Jetson Nano 作为 NVIDIA 推出的入门级边缘 AI 计算平台,虽然在计算能力上相比高端 GPU有所限制,但在功耗控制和成本效益方面表现优异,特别适合对功耗敏感的边缘部署场景…...
OpenClaw故障排查大全:千问3.5-27B接口连接7类错误解决
OpenClaw故障排查大全:千问3.5-27B接口连接7类错误解决 1. 为什么需要这份排查指南 上周我在本地部署千问3.5-27B模型时,OpenClaw死活连不上模型接口。那天晚上我对着ECONNREFUSED错误折腾到凌晨两点,试了各种方法才发现是网关端口被占用了…...
同事离职,他在大群里发了一句“感谢一路相伴,江湖再见”,刚发出去,HR就让他撤回,理由是工作群不要发与工作无关的内容。
今天摸鱼的时候,听到一个极其荒诞又极其现实的职场鬼故事。隔壁部门的老李提了离职,今天是last day。这哥们儿可能平时武侠小说看多了,临走前在几百人的公司大群里发了一句:“感谢一路相伴,江湖再见”。结果呢…...
【GUI-Agent】阶跃星辰 GUI-MCP 解读---()---命令解析和工具映射蓉
先回顾:三次握手(建立连接)核心流程(实际版) 为了让挥手流程衔接更顺畅,咱们先快速回顾三次握手的实际核心,避免上下文脱节: 第一步(客户端→服务器)…...
