数据结构-哈希表

一、哈希表的定义与核心本质

• 别称:散列表,是 键(Key)-值(Value) 映射的高效数据结构

• 核心原理:通过 哈希函数(Hash Function) 将键转换为数组索引,直接访问对应值,实现 O(1) 级别的平均查找、插入、删除效率

• 本质:用空间换时间,通过哈希函数减少查找时的比较次数,是数组查找的优化延伸

二、哈希表的核心组成

  1. 哈希函数(Hash Function)

◦ 作用:将任意类型的键(字符串、数字等)映射为固定范围的整数(数组索引)

◦ 设计要求:

◦ 确定性:同一键必须映射到同一索引

◦ 高效性:计算过程简单,耗时短

◦ 均匀性:键分布均匀,减少索引冲突

◦ 防碰撞性:尽量避免不同键映射到同一索引

◦ 常见设计方法:

◦ 直接定址法:键→索引直接对应(如键为身份证号,取后几位作为索引)

◦ 除留余数法:index = key % 数组长度(最常用,需选质数作为数组长度)

◦ 数字分析法:提取键中分布均匀的部分作为索引(如手机号后4位)

◦ 折叠法:将键拆分后叠加,取结果作为索引(如长数字拆分成多段求和)

◦ 字符串哈希:将字符ASCII码加权求和后取模(如 hash(s) = (s[0]×31ⁿ⁻¹ + s[1]×31ⁿ⁻² + ... + s[n-1]) % 数组长度)

  1. 哈希表(数组)

◦ 存储载体:连续的数组空间,每个索引位置称为 桶(Bucket),用于存储键值对

◦ 数组长度选择:通常设为质数,减少除留余数法的冲突概率

  1. 冲突解决机制

◦ 冲突定义:不同键通过哈希函数得到同一索引(无法避免,只能缓解)

◦ 开放寻址法(闭散列):

◦ 核心:冲突时,按某种规则在数组中寻找下一个空闲桶

◦ 常见方式:

◦ 线性探测:冲突后依次检查下一个索引(index+1, index+2...,易产生聚集)

◦ 二次探测:冲突后按索引±1²、±2²...查找(减少聚集,需数组长度为4k+3型质数)

◦ 双重哈希:用第二个哈希函数计算步长,步长=hash2(key)(分散性最好,避免聚集)

◦ 缺点:数组满时无法插入,删除需标记"已删除"(避免影响后续查找)

◦ 链地址法(开散列):

◦ 核心:每个桶对应一个链表(或红黑树),冲突的键值对依次存入链表中

◦ 优点:冲突处理简单,数组利用率高,删除方便(直接删除链表节点)

◦ 优化:当链表长度超过阈值(如8),转为红黑树(Java HashMap的实现方式),提升查询效率

◦ 其他方法:

◦ 再哈希法:冲突时调用另一个哈希函数重新计算索引

◦ 公共溢出区:将所有冲突的键值对存入单独的溢出数组

三、哈希表的关键性能指标

• 负载因子(Load Factor):α = 存储的键值对数量 / 数组长度

◦ 意义:衡量哈希表的拥挤程度,α越小,冲突概率越低,效率越高

◦ 阈值:通常α阈值设为0.75(Java HashMap默认),超过则触发 扩容(Resizing)

• 扩容机制:

◦ 过程:创建新的更大数组(通常是原长度的2倍,且为质数),重新计算所有键的哈希值并迁移到新数组

◦ 目的:降低负载因子,减少后续冲突,保证效率稳定

四、哈希表的优缺点

  1. 优点:

◦ 平均时间复杂度:查找、插入、删除均为 O(1),效率远超数组、链表、树

◦ 键值对映射直接,无需遍历,适合高频查找场景

  1. 缺点:

◦ 最坏时间复杂度:O(n)(哈希函数极差或负载因子过高,导致所有键冲突,链表长度过长)

◦ 空间利用率较低(需预留扩容空间,开放寻址法浪费更多空间)

◦ 无序存储:键值对无固定顺序,无法按索引有序访问

◦ 哈希函数设计难度高:需兼顾均匀性、高效性,否则影响性能

五、常见应用场景

• 数据缓存:如Redis、浏览器缓存(键为URL,值为缓存内容)

• 快速查找:字典查询、用户信息查询(键为用户名/ID,值为用户数据)

• 去重操作:如日志去重、数组去重(利用键的唯一性)

• 键值对存储:数据库索引、哈希映射(HashMap)、哈希集合(HashSet,仅存键)

相关推荐
不会代码的小猴1 天前
Linux环境编程第六天笔记--system-V IPC
linux·笔记
Hx_Ma161 天前
SpringMVC框架提供的转发和重定向
java·开发语言·servlet
乌恩大侠1 天前
【笔记】USRP 5G 和 6G 参考架构
笔记·5g
biuyyyxxx1 天前
Python自动化办公学习笔记(一) 工具安装&教程
笔记·python·学习·自动化
期待のcode1 天前
原子操作类LongAdder
java·开发语言
舟舟亢亢1 天前
Java集合笔记总结
java·笔记
L_09071 天前
【C++】高阶数据结构 -- 红黑树
数据结构·c++
小酒窝.1 天前
【多线程】多线程打印ABC
java
丝斯20111 天前
AI学习笔记整理(66)——多模态大模型MOE-LLAVA
人工智能·笔记·学习
乡野码圣1 天前
【RK3588 Android12】RCU机制
java·jvm·数据库