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

哈希表实战:从原理到手写实现

一、先解答上次的思考题

数组[5,2,8,1,3]建成大顶堆后,依次取出堆顶结果:8 5 3 2 1


二、今天学习目标

  1. 什么是哈希表、哈希函数、哈希冲突
  2. 解决冲突:链地址法(拉链法)
  3. 手写实现一个简易哈希表
  4. 支持:插入、查找、删除操作

三、什么是哈希表?

哈希表(Hash Table)也叫散列表,核心思想:用 key 直接计算出存储位置,实现近乎 O (1) 的查找。

  • 数组:下标是数字,查找 O (1)
  • 哈希表:key 可以是数字 / 字符串,通过哈希函数转成数组下标

关键概念

  1. 哈希函数:把 key 转成数组下标最简单:index = key % 表长度
  2. 哈希冲突:两个不同 key 算出同一个 index
  3. 冲突解决:最常用链地址法(同一位置挂一条链表)

四、结构设计(链地址法)

  • 数组作为哈希桶
  • 每个桶是一个链表,存放冲突的元素
哈希表结构示意: [0] → (key,val) → NULL [1] → NULL [2] → (key,val) → (key,val) → NULL ...

五、完整可运行代码(简易哈希表)

#include <stdio.h> #include <stdlib.h> // 哈希表大小 #define SIZE 10 // 链表节点 struct Node { int key; int val; struct Node* next; }; // 哈希表:数组存链表头 struct Node* hashTable[SIZE]; // 初始化哈希表 void initHashTable() { for (int i = 0; i < SIZE; i++) hashTable[i] = NULL; } // 哈希函数 int hashFunc(int key) { return key % SIZE; } // 插入 key-value void insert(int key, int val) { int index = hashFunc(key); struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->key = key; newNode->val = val; newNode->next = NULL; // 头插法 newNode->next = hashTable[index]; hashTable[index] = newNode; } // 查找:根据 key 找 val,找到返回1,否则0 int find(int key, int* resVal) { int index = hashFunc(key); struct Node* cur = hashTable[index]; while (cur != NULL) { if (cur->key == key) { *resVal = cur->val; return 1; } cur = cur->next; } return 0; } // 删除 key void delete(int key) { int index = hashFunc(key); struct Node* cur = hashTable[index]; struct Node* pre = NULL; while (cur != NULL && cur->key != key) { pre = cur; cur = cur->next; } if (cur == NULL) return; if (pre == NULL) hashTable[index] = cur->next; else pre->next = cur->next; free(cur); } // 打印哈希表 void printHashTable() { for (int i = 0; i < SIZE; i++) { printf("[%d] ", i); struct Node* cur = hashTable[i]; while (cur != NULL) { printf("→ (%d:%d) ", cur->key, cur->val); cur = cur->next; } printf("\n"); } } // ==================== 主函数测试 ==================== int main() { initHashTable(); insert(1, 100); insert(2, 200); insert(11, 1100); // 11%10=1,与1冲突 insert(21, 2100); // 21%10=1,继续冲突 printf("哈希表内容:\n"); printHashTable(); int val; if (find(11, &val)) printf("\n找到 key=11,val=%d\n", val); delete(11); printf("\n删除 key=11 后:\n"); printHashTable(); return 0; }

六、运行结果

哈希表内容: [0] [1] → (21:2100) → (11:1100) → (1:100) [2] → (2:200) [3] [4] [5] [6] [7] [8] [9] 找到 key=11,val=1100 删除 key=11 后: [0] [1] → (21:2100) → (1:100) [2] → (2:200) [3] [4] [5] [6] [7] [8] [9]

七、哈希表总结

  • 查找 / 插入 / 删除平均复杂度:O(1)
  • 冲突最坏情况退化为链表:O(n)
  • 工程常用:unordered_map、Redis 哈希、数据库索引

八、今日小练习

  1. 插入 key:5,15,25,7
  2. 打印哈希表,观察冲突位置
  3. 查找 key=15,删除 key=5
http://www.jsqmd.com/news/628186/

相关文章:

  • 前端性能优化:从加载速度到渲染性能的全面突破
  • 如何使用 PvZ Toolkit:植物大战僵尸修改工具终极指南
  • OBS-VST深度解析:如何在OBS Studio中实现专业级音频处理
  • 网盘直链下载助手终极指南:八大网盘真实链接一键获取,轻松告别下载限速
  • 解锁全平台游戏控制:GlosSI让Steam手柄畅玩任何游戏
  • 【CTF】【二进制分析】深入解析JPG文件结构:从段标识到霍夫曼编码
  • 3分钟快速上手:免费开源的多平台资源下载神器res-downloader终极指南
  • VideoDownloadHelper深度解析:网页视频下载的技术实现与实战应用
  • Qwen-Image-Edit-2511多人合影换装:保持比例,统一风格
  • NoFences桌面分区终极指南:免费打造整洁高效的Windows桌面
  • 深入探索OpenHands:从架构设计到实际应用的全方位解析
  • 终极DLSS版本管理器:一键优化多游戏画质的完整指南
  • 终极Windows 11安装指南:MediaCreationTool.bat解决TPM检测与系统升级难题
  • S2-Pro大模型Java开发实战:集成SpringBoot构建智能问答微服务
  • 万象视界灵坛实战案例:跨境电商商品图自动匹配多语言语义标签系统
  • TextMeshPro 渐变色进阶:从字符到段落的贴图映射艺术
  • 英语阅读_its not everything
  • 导师看了都说绝!PaperXie 一键驯服毕业论文格式,4000 + 高校模板直接抄作业
  • AMD Ryzen深度调试突破:5个实战场景掌握SMUDebugTool核心功能
  • 南开计算机复试C/C++编程能力测试怎么考?我用亲身经历告诉你备考重点和避坑指南
  • PvZ Toolkit终极指南:如何轻松掌控植物大战僵尸游戏体验
  • 5分钟掌握Translumo:实时屏幕翻译神器,打破游戏视频语言壁垒
  • Mermaid在线编辑器:3步打造专业技术图表的实用指南
  • Docker化Oracle 10G:从镜像拉取到连接测试的完整实践
  • SecGPT-14B快速部署:CSDN平台内开箱即用的安全大模型服务体验指南
  • 用eNSP模拟校园网毕设项目,从VLAN划分到防火墙策略的保姆级排错复盘
  • 2026年中国红光面石材厂家哪家实惠:红色花岗岩石材厂家、花岗岩石材厂家批发、花岗岩荒料加工厂、雅蒙黑火烧面花岗岩选择指南 - 优质品牌商家
  • Perseus补丁:3步解锁碧蓝航线全皮肤的终极免费指南
  • 电子工程师必看:如何用复合管设计高增益放大电路(附Multisim仿真文件)
  • 深入解析SyncE:以太网频率同步的关键技术与应用