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

哈希表入门教程:从零搭建完整结构

一、什么是哈希表1.核心定义哈希表 数组哈希函数冲突解决哈希表是一种通过哈希函数将「键Key」映射到「索引Index」从而实现O (1) 平均时间复杂度查找、插入、删除的数据结构。2.核心三要素1键key 要存储的数据标识如数字、字符串、对象。2哈希函数把 Key 转换成数组下标的函数核心3哈希表底层数组利用数组随机访问特性3.核心优势1平均查找 / 插入 / 删除 O(1)2最坏O (n)3对比数组查找 O (n)链表查找 O (n)二叉搜索树查找 O (logn)哈希表是最快的查找数据结构二、哈希函数和哈希冲突1.哈希函数Hash Function作用key - 数组索引公式index hashkey% 数组长度2.哈希函数高频坑点1不处理负数key-下标越界崩溃// ❌ 错误哈希函数 int bad_hash1(HashTable* ht, int key) { return key % ht-size; // 负数key → 负数下标 }错误原因key -1 % 10 -1→ 数组下标不能为负程序直接崩溃。正确代码// ✅ 正确哈希函数 int good_hash(HashTable* ht, int key) { if (key 0) key -key; // 必须先转正数 return key % ht-size; }2哈希函数分布不均 - 冲突爆炸// ❌ 错误哈希函数所有key都返回同一个下标 int bad_hash2(HashTable* ht, int key) { return 0; // 所有元素都存在下标0 → 链表变成长链O(n)复杂度 }错误原因冲突严重哈希表退化为链表。正确代码// 正确哈希函数保证分布均匀 处理负数 int hash(HashTable* ht, int key) { // 1. 处理负数key避免负数下标越界 if (key 0) { key -key; } // 2. 取余运算将key映射到[0, size-1]的合法下标 // 配合质数大小的哈希表能最大程度保证分布均匀 return key % ht-size; }(3)哈希表大小用偶数 - 冲突增多// ❌ 不推荐 HashTable* ht createHashTable(10); // 偶数取余分布不均 // ✅ 推荐质数大小 HashTable* ht createHashTable(11); // 质数分布均匀冲突最少3.哈希冲突定义两个不同的 Key通过哈希函数算出了同一个索引。无法完全避免只能解决冲突。4.哈希冲突的解决办法1链地址法链表数组数组每个位置存一个链表 / 红黑树冲突时把元素追加到链表后面优点实现简单无空间浪费2开放寻址法纯数组冲突时向后找空位置存放线性探测 / 二次探测优点无链表内存连续缺点删除麻烦容易堆积三、哈希表基本操作总结1.链表节点typedef struct Node{ int key; //键 int value; //值 struct Node* next; //用于解决指针冲突 }Node;2.哈希表结构typedef struct HashTable{ int size; //数组长度 Node** table; //指针数组存链表头 }HashTable;3.哈希函数核心公式正确哈希函数abs(key) % size作用把任意整数 → 合法下标 [0, size-1]必须处理负数否则下标越界崩溃int hash(HashTable* ht, int key) { if (key 0) key -key; // 负数转正数 return key % ht-size; // 取余映射下标 }4.创建哈希表HashTable* createHashTable(int size) { HashTable* ht (HashTable*)malloc(sizeof(HashTable)); ht-size size; ht-table (Node**)malloc(sizeof(Node*) * size); // 初始化所有链表为空 for (int i 0; i size; i) { ht-table[i] NULL; } return ht; }5.创建节点Node* createNode(int key, int value) { Node* node (Node*)malloc(sizeof(Node)); node-key key; node-value value; node-next NULL; return node; }6.插入冲突处理void insert(HashTable* ht, int key, int value) { int index hash(ht, key); // 计算下标 Node* head ht-table[index]; // 遍历key已存在则覆盖 Node* cur head; while (cur) { if (cur-key key) { cur-value value; return; } cur cur-next; } // 头插法新节点放链表头部 Node* newNode createNode(key, value); newNode-next head; ht-table[index] newNode; }7.查找int search(HashTable* ht, int key) { int index hash(ht, key); Node* cur ht-table[index]; // 遍历链表查找 while (cur) { if (cur-key key) return cur-value; cur cur-next; } return -1; // 未找到 }8.删除void deleteKey(HashTable* ht, int key) { int index hash(ht, key); Node* prev NULL; Node* cur ht-table[index]; // 查找节点 while (cur cur-key ! key) { prev cur; cur cur-next; } if (!cur) return; // 不存在直接返回 // 删除节点 if (!prev) ht-table[index] cur-next; // 删头节点 else prev-next cur-next; // 删中间节点 free(cur); }9.销毁防止内存泄露void destroyHashTable(HashTable* ht) { for (int i 0; i ht-size; i) { Node* cur ht-table[i]; while (cur) { Node* temp cur; cur cur-next; free(temp); } } free(ht-table); free(ht); }10.一般经常会使用到的方法int hash[N]{0} 来进行下标映射。四、哈希表算法分类哈希表的核心思想只有一个把 key 转成下标然后快速存、快速查。数组哈希做题比较常用它把 “链表” 扔掉直接用一个数组当下标映射思想还是哈希表key → 下标 → 存值。1.两数之和查找配对// 两数之和数组哈希版适合数据范围小的场景 int* twoSum(int* nums, int numsSize, int target, int* returnSize) { *returnSize 2; int* res (int*)malloc(2 * sizeof(int)); // 数组哈希key数值value下标偏移量处理负数 int hash[200001]; memset(hash, -1, sizeof(hash)); // 初始化为-1表示未访问 for (int i 0; i numsSize; i) { int complement target - nums[i]; int idx complement 100000; // 找到配对的数返回下标 if (hash[idx] ! -1) { res[0] hash[idx]; res[1] i; return res; } // 把当前数存入哈希 int cur_idx nums[i] 100000; hash[cur_idx] i; } return res; }一次遍历哈希表 O (1) 查找时间 O (n)。2.频率统计计数// 小写字母统计26大小 int hash[26] {0}; for (int i 0; i strlen(s); i) { hash[s[i] - a]; // 字符转下标计数1 } // 全ASCII字符统计128大小万能 int hash[128] {0}; for (int i 0; i strlen(s); i) { hash[(unsigned char)s[i]]; }3.去重// 数字去重带偏移量处理负数 int hash[200001] {0}; // 覆盖-100000~100000 for (int i 0; i numsSize; i) { int idx nums[i] 100000; // 负数偏移转正数下标 if (hash[idx]) return true; // 已存在→有重复 hash[idx] 1; // 标记已访问 } return false;4.键值映射bool isIsomorphic(char* s, char* t) { int map_s[128], map_t[128]; memset(map_s, -1, sizeof(map_s)); memset(map_t, -1, sizeof(map_t)); int len strlen(s); for (int i 0; i len; i) { unsigned char c1 s[i], c2 t[i]; // 双向映射不一致返回false if (map_s[c1] ! map_t[c2]) return false; // 建立双向映射 map_s[c1] i; map_t[c2] i; } return true; }5.前缀和哈希表int subarraySum(int* nums, int numsSize, int k) { // 数组哈希记录前缀和出现的次数偏移量处理负数 int hash[200001] {0}; hash[100000] 1; // 初始前缀和为0出现1次 int preSum 0, count 0; for (int i 0; i numsSize; i) { preSum nums[i]; // 查找preSum - k出现的次数 int target preSum - k; int idx target 100000; if (idx 0 idx 200001) { count hash[idx]; } // 更新当前前缀和的次数 int cur_idx preSum 100000; hash[cur_idx]; } return count; }6.滑动窗口去重int lengthOfLongestSubstring(char* s) { int hash[128]; // 记录字符最后出现的位置 memset(hash, -1, sizeof(hash)); int left 0, maxLen 0; int len strlen(s); for (int right 0; right len; right) { unsigned char c s[right]; // 字符已在窗口内移动左指针到重复位置的下一位 if (hash[c] left) { left hash[c] 1; } // 更新字符的最新位置 hash[c] right; maxLen (right - left 1) maxLen ? (right - left 1) : maxLen; } return maxLen; }五、高频出错点1.C 语言必须手动 free → 内存泄漏先 free 链表 → 再 free 数组 → 最后 free 哈希表2.直接访问数组下标 → 空指针崩溃ht-table[index]-key错误必须用search()函数安全查找正确3.插入重复 key 不覆盖 → 数据错误插入前必须遍历检查相同 key 覆盖 value4.认为哈希表永远 O (1) → 认知错误哈希冲突严重时 O (n)

相关文章:

哈希表入门教程:从零搭建完整结构

一、什么是哈希表?1.核心定义哈希表 数组 哈希函数 冲突解决哈希表是一种通过哈希函数将「键(Key)」映射到「索引(Index)」,从而实现O (1) 平均时间复杂度查找、插入、删除的数据结构。2.核心三要素&…...

2025届毕业生推荐的降重复率神器解析与推荐

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 如果要降低AIGC检测率,那就得着重从文本特征方面着手。首先,词汇多样…...

crypto-js —— 前端数据安全的 JavaScript 加密利器

1. 为什么前端开发需要数据加密? 想象一下这样的场景:你在网上填写了一份包含个人信息的表单,点击提交后,这些数据会以明文形式在网络中传输。如果有人在传输过程中截获了这些数据,你的隐私就会完全暴露。这就是为什么…...

9. C++14新特性-std::tuple 的按类型寻址 (Type-based Tuple Addressing)

一、引言在现代 C 中,当我们想要在一个函数中返回多个不同类型的值,或者临时打包几个数据时,std::tuple(元组)是最标准的容器。然而,C11 提供的基于索引的元组访问方式,在工程实践中暴露出严重的…...

金融级权限设计实战:用RBAC3模型搞定互斥角色、基数限制与操作审计

金融级权限架构设计:基于RBAC3模型的合规实战指南 在金融行业数字化转型浪潮中,权限管理系统不仅是技术组件,更是合规生命线。某跨国银行曾因角色权限漏洞导致数千万美元误操作,最终面临监管重罚——这个真实案例揭示了权限设计在…...

Win10/Win11远程桌面报错‘函数不受支持’?5分钟搞定CredSSP加密Oracle修正

Win10/Win11远程桌面报错‘函数不受支持’?5分钟急救指南 刚准备远程处理工作文件,突然跳出"发生身份验证错误,要求的函数不受支持"的红色警告框——这个场景对需要频繁使用远程桌面的职场人来说简直噩梦。上周我就遇到了同样问题&…...

OZON平台选品指南:揭秘俄罗斯市场的潜力品牌与爆款趋势

对于跨境电商卖家而言,俄罗斯市场正成为一片充满机遇的蓝海。作为俄罗斯本土最大的综合电商平台,OZON的用户规模和消费潜力持续增长。然而,机遇往往伴随着挑战,如何在庞大的商品海洋中精准捕捉爆款,规避风险&#xff0…...

FreeRADIUS配置踩坑记:当LDAP用户遇上Google Authenticator,如何解决PAM模块的那些‘坑’?

FreeRADIUS与LDAP集成Google Authenticator的实战避坑指南 当企业安全团队决定为远程访问系统部署双因素认证时,FreeRADIUS与LDAP集成Google Authenticator的方案常被列为优选。但真正实施时,技术细节中的"魔鬼"往往让工程师们夜不能寐。本文将…...

Yii2的$app->handleRequest($request)的本质的庖丁解牛

$app->handleRequest($request) 是 Yii2 框架运行时心脏的每一次搏动。 如果说 new Application() 是**“创世”(构建世界),那么 $app->handleRequest($request) 就是“演化”(处理事件)。 它是整个 MVC 流程的总…...

最新扫码点餐外卖配送餐饮小程序系统源码

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示一、详细介绍 最新扫码点餐外卖配送餐饮小程序系统源码 系统功能: 1.支持多平台:微信小程序,支付宝小程序,和H5平台,页面可以后台DIY管理。 2.小程序页面支…...

MaterialSkin:让WinForms应用焕发现代设计光彩的主题框架

MaterialSkin:让WinForms应用焕发现代设计光彩的主题框架 【免费下载链接】MaterialSkin Theming .NET WinForms, C# or VB.Net, to Googles Material Design Principles. 项目地址: https://gitcode.com/gh_mirrors/ma/MaterialSkin 在传统Windows桌面应用开…...

在CentOS 7.9上,我如何用Ollama+DeepSeek-R1+RAGFlow搭建了一个完全离线的AI知识库(保姆级避坑指南)

在CentOS 7.9上构建离线AI知识库:OllamaDeepSeek-R1RAGFlow实战全记录 最近在帮一家金融机构搭建内部知识库时,遇到了一个棘手的需求:所有AI组件必须完全离线运行,且要部署在已经服役5年的CentOS 7.9服务器上。经过两周的折腾&…...

UIO与CCP917T驱动开发实战

1、UIO基础2、UIO和CCP917T结合3、和内核驱动结合...

别再只懂Diffusion了!Flow Matching如何用更简单的思路搞定生成模型?

Flow Matching:用概率流重构生成模型的未来 当我们在谈论生成模型时,扩散模型(Diffusion Models)无疑是当前最耀眼的明星。从图像生成到分子设计,扩散模型以其卓越的生成质量和理论优雅性征服了无数应用场景。然而&am…...

开源歌词工具技术解析:跨平台音乐资源整合与高效处理方案

开源歌词工具技术解析:跨平台音乐资源整合与高效处理方案 【免费下载链接】163MusicLyrics 云音乐歌词获取处理工具【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 开源歌词工具作为一款专注于音乐资源处理的解决方案…...

VSCode 自动更新问题解决记录

VSCode 自动更新问题解决记录 问题 今天发现 VSCode 的"帮助"菜单里没有「检查更新」选项,软件也不会自动提示新版本,每次都需要手动去官网下载更新。网上搜了一下,发现 VSCode 其实是支持自动更新的,但我的就是没有这个…...

10、Ansible 生产级故障排查与运维最佳实践

Ansible 生产级故障排查与运维最佳实践 一、Ansible 生产常见故障类型(高频) SSH 连接类故障(占 60%)sudo/权限类故障网络、端口、防火墙Python 环境缺失/版本不兼容Fact 采集慢、超时、卡死文件权限、临时目录权限变量、模板、加…...

零基础玩转DeepSeek-R1推理模型:Ollama一键部署Llama-8B教程

零基础玩转DeepSeek-R1推理模型:Ollama一键部署Llama-8B教程 1. 引言:为什么选择DeepSeek-R1-Distill-Llama-8B 你是否想体验强大的文本生成能力,却被复杂的模型部署流程劝退?DeepSeek-R1-Distill-Llama-8B是一个经过优化的8B参…...

OpenClaw+Phi-3-vision-128k-instruct低成本方案:自建多模态助手避坑指南

OpenClawPhi-3-vision-128k-instruct低成本方案:自建多模态助手避坑指南 1. 为什么选择本地部署多模态助手 去年我尝试用商业API搭建个人知识管理助手时,发现两个痛点:一是处理PDF和图片的token消耗像流水一样快,二是长文档分析…...

24小时运行不中断:OpenClaw+Qwen3-32B监控网站变更并邮件报警

24小时运行不中断:OpenClawQwen3-32B监控网站变更并邮件报警 1. 为什么需要自动化网站监控? 去年我负责一个竞品分析项目时,每天要手动检查十几个竞争对手官网的更新情况。某天凌晨两点,竞品突然上线了关键功能更新,…...

Massachusetts:1类道路语义分割数据集Massachusetts数据集包括1个类别类别分别是:road 共计图片809张,分辨率是1500x1500像素数据集是VOC格式训练集图

Massachusetts:1类道路语义分割数据集 Massachusetts数据集包括1个类别 类别分别是:road 共计图片809张,分辨率是1500x1500像素 数据集是VOC格式 训练集图片647张,验证集81张、测试集图片有81 相关UNet、FCN、DeepLabV3、Segform…...

高品质订单车后台管理系统,支持excel订单导入功能,实现全面的管理功能,打造智能化管理系统

订单车后台管理系统,自己开发的,基本功能齐全,支持excel订单导入功能,最近在折腾一个自己用的订单车后台管理系统,核心功能基本跑通了。最让我得意的其实是Excel导入功能——这玩意儿看起来简单,实际处理起…...

Blender3mfFormat插件全攻略:从安装配置到3D打印工作流优化

Blender3mfFormat插件全攻略:从安装配置到3D打印工作流优化 【免费下载链接】Blender3mfFormat Blender add-on to import/export 3MF files 项目地址: https://gitcode.com/gh_mirrors/bl/Blender3mfFormat Blender3mfFormat插件是一款专为Blender设计的3MF…...

终极指南:如何5分钟免费安装Fooocus AI图像生成软件

终极指南:如何5分钟免费安装Fooocus AI图像生成软件 【免费下载链接】Fooocus Focus on prompting and generating 项目地址: https://gitcode.com/GitHub_Trending/fo/Fooocus Fooocus是一款专注于提示词和图像生成的AI图像生成软件,它重新定义了…...

倒排索引详解

文章目录倒排索引(Inverted Index)正排索引与倒排索引实现优缺点倒排索引(Inverted Index) 倒排索引是信息检索领域最核心的数据结构,几乎所有搜索引擎(Google、Elasticsearch、Lucene)都基于它…...

e1547:让社区浏览体验回归纯粹的定制化浏览器

e1547:让社区浏览体验回归纯粹的定制化浏览器 【免费下载链接】e1547 A sophisticated e621 browser 项目地址: https://gitcode.com/gh_mirrors/e1/e1547 问题引入:当浏览变成筛选的艺术 在内容爆炸的时代,每位用户都渴望看到真正感…...

新手福音:通过快马平台零代码基础玩转picoclaw机器人板

作为一个刚接触嵌入式开发的新手,拿到picoclaw控制器时既兴奋又忐忑。这块小小的板子能控制电机、读取传感器,但如何让它动起来却让我一头雾水。好在发现了InsCode(快马)平台,不需要从零开始啃文档,就能快速生成可运行的示例代码。…...

Kali 2025.4上部署HexStrike AI踩坑实录:从MCP连接失败到完美运行的完整排错指南

Kali 2025.4上部署HexStrike AI踩坑实录:从MCP连接失败到完美运行的完整排错指南 HexStrike AI作为新一代AI驱动的渗透测试框架,理论上只需几条命令就能完成部署。但现实往往比文档复杂得多——特别是当你在深夜赶项目,却发现MCP客户端死活连…...

NVIDIA Profile Inspector完整指南:解锁显卡隐藏性能的终极免费工具

NVIDIA Profile Inspector完整指南:解锁显卡隐藏性能的终极免费工具 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 还在为游戏卡顿、画面撕裂而烦恼吗?NVIDIA Profile Inspecto…...

2026年在职研究生论文降AI工具推荐:理论与实践结合部分如何处理

2026年在职研究生论文降AI工具推荐:理论与实践结合部分如何处理 导师发消息说论文AI率超标的时候,我正在食堂吃饭。筷子都差点拿不稳。 后来用了三天时间研究在职研究生论文降AI,踩了不少坑但总算搞定了。最后稳定在用的就是嘎嘎降AI&#…...