【数据结构】 散列表

一、散列表基本概念

散列表又称哈希表,是一种以关键字直接寻址为核心的高效查找结构。顺序查找、折半查找、二叉树、B 树等查找方式,都需要通过关键字多次比较才能确定元素位置,查找效率依赖比较次数;而散列表完全打破 "比较式查找" 逻辑,通过散列函数(哈希函数),直接将元素的关键字映射为数组下标,一步定位存储位置,实现近似 O (1) 的平均时间复杂度查找,是所有查找结构中效率最高的类型。

散列表的核心思想:位置 = H (key)。以一片连续存储空间(数组)作为基础表,利用哈希函数计算关键字对应的存储地址,将元素直接存入该地址;查找时,对目标关键字执行相同哈希运算,直接访问对应地址读取元素,最大限度减少查找开销。理想状态下,每个关键字对应唯一地址,无需任何比较,存取瞬间完成。


二、散列函数与设计原则

散列函数是散列表的核心,作用是将任意长度、任意形式的关键字,压缩映射为合法的数组下标。优秀的散列函数必须满足三大原则:计算简单高效、地址分布均匀、尽量减少冲突。

常用散列函数:

除留余数法(考试最常考)

公式:H(key)=key mod p

要求:p 取小于表长的质数或无公因数合数,能最大程度避免地址集中堆积,分布均匀,计算简单,适用性最强。

直接定址法

直接以关键字本身或线性运算结果作为地址,适合关键字连续分布的场景,无冲突,适用范围窄。

数字分析法

提取关键字中分布随机的数位作为地址,适用于已知规律的固定关键字集合。

平方取中法

对关键字平方后截取中间几位作为地址,通过平方打乱原始规律,分散地址。


三、哈希冲突的本质

哈希冲突:不同关键字,经过哈希函数计算,得到相同存储地址,即

key 1=key 2,但 H(key 1)=H(key 2 )

冲突无法完全避免:关键字范围无限,散列表存储空间有限,有限地址映射无限关键字,必然存在碰撞。因此,散列表设计分为两大核心:合理的哈希函数 + 完善的冲突处理方法,二者缺一不可,也是散列表学习的重点难点。


四、两大冲突解决方法

  1. 开放定址法

原理:当目标地址被占用时,按照固定规则向后探测,寻找表中空闲位置存入元素,所有数据全部存储在原始散列表数组内。常见探测方式:

线性探测:冲突时依次向后 + 1 寻址,简单易实现,但易产生堆积现象,连续位置被占用,降低查找效率;

二次探测:以平方步长跳跃寻址,缓解线性堆积;

双重哈希:使用第二个哈希函数计算步长,地址分布更均匀。

开放定址法特点:结构紧凑、无需额外空间,但删除元素不能直接清空(会截断探测路径),只能做删除标记,操作受限。

  1. 链地址法(拉链法)

原理:散列表每个数组单元不直接存数据,而是作为单链表头结点;所有哈希地址相同的元素,全部挂载在同一条链表中。发生冲突时,直接追加到链表尾部,互不干扰。

特点:完全杜绝堆积问题,插入删除灵活,仅冲突位置消耗链式空间;查找时先定位数组下标,再遍历短链表,平均效率极高,是实际工程中最常用的方式。


五、散列表的查找过程

计算目标关键字哈希地址;

访问该地址单元,若关键字相等,查找成功;

若不相等或存在冲突,根据冲突解决策略继续探测 / 遍历链表;

遍历至空闲位置或链表末尾仍无匹配元素,判定查找失败。

散列表查找效率不依赖元素总数,只取决于:哈希函数优劣、冲突处理方式、装填因子。


六、装填因子

装填因子公式:元素个数散列表长度α 越小:数组空闲单元多,冲突概率低,查找越快,空间利用率低;α越大:空间利用率高,元素拥挤,冲突剧增,查找效率急剧下降。

一般规范:散列表装填因子控制在 0.6~0.9 之间,平衡空间与效率。开放定址法因易堆积,装填因子需更小;链地址法容忍度更高,可适当增大。


七、散列表的优缺点总结

优点

平均查找、插入、删除时间复杂度 O(1),效率碾压顺序查找、折半查找、树形查找;

寻址逻辑简单,无需关键字多次比较;

适合海量数据高频增删、快速检索场景。

缺点

无法支持有序遍历、范围查询,仅适合精准匹配;

哈希冲突会退化效率,最坏情况退化为线性查找;

存储空间存在冗余,开放定址法利用率受装填因子限制;

关键字必须可哈希,部分复杂数据类型映射困难。


八、整体总结

散列表是一种直接寻址的高效查找结构,区别于传统比较类查找,依靠哈希函数实现关键字到存储地址的直接映射。哈希冲突是固有问题,通过开放定址法、链地址法可有效解决;装填因子直接决定整体性能。在计算机系统中,哈希表广泛应用于缓存、字典、数据库索引、集合去重等场景,是数据结构中实用性最强的结构之一。虽然无法实现有序操作,但在精准查询场景下,无可替代。

相关推荐
zh_xuan4 小时前
LeeCode 496. 下一个更大元素I
数据结构·算法·栈·单调栈
白杨尚青7 小时前
C++进阶篇(五):红黑树——四条规则、三种插入情况与旋转变色
开发语言·数据结构·c++·stl·红黑树·平衡二叉树
likexuec1 天前
数据结构(2)
数据结构
D e re k ZH1 天前
C++ 标准库算法全景指南
数据结构·c++·算法
冻柠檬飞冰走茶1 天前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
十二2 天前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
D e re k ZH2 天前
C++ 从零入门(一):基础语法与程序结构
数据结构·c++·算法
careathers2 天前
【数据结构】基于比较的排序算法 - 交换排序
数据结构·算法·排序算法
H.莓飛2 天前
【C++】【STL】vector_OJ题
linux·服务器·开发语言·数据结构·c++·visual studio
老师我太想进步了20263 天前
【数据结构-4】算法美学之顺序表
数据结构·算法