【数据结构】 散列表

一、散列表基本概念

散列表又称哈希表,是一种以关键字直接寻址为核心的高效查找结构。顺序查找、折半查找、二叉树、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),效率碾压顺序查找、折半查找、树形查找;

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

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

缺点

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

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

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

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


八、整体总结

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

相关推荐
承渊政道2 小时前
【动态规划算法】(简单多状态dp问题入门与经典题型解析)
数据结构·c++·学习·算法·leetcode·macos·动态规划
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题】【Java基础篇】第16题:HashMap中Key为null时,元素存放的位置
java·开发语言·面试·哈希算法·散列表
嘻嘻哈哈樱桃2 小时前
牛客经典101题题解集--哈希
java·数据结构·python·算法·leetcode·职场和发展·哈希算法
自我意识的多元宇宙2 小时前
【数据结构】 红黑树
数据结构·算法
我不是懒洋洋2 小时前
【数据结构】二叉树链式结构的实现(二叉树的遍历、使用二叉树的基本方法、二叉树的创建和销毁)
c语言·数据结构·c++·经验分享·算法·链表·visual studio
如君愿2 小时前
考研复习 Day 24 | 习题--计算机网络第二章(物理层)、数据结构(栈与队列)
数据结构·计算机网络·考研·课后习题·记录考研
qeen8713 小时前
【数据结构】树的基本概念及存储
c语言·数据结构·c++·学习·
一江寒逸13 小时前
数据结构与算法之美:串(字符串)——从基础操作到KMP模式匹配,吃透面试最高频的字符串考点
数据结构·面试·职场和发展
hi_ro_a14 小时前
C++ 哈希表封装 unordered_map /unordered_set
数据结构·c++·算法·哈希算法