哈希的概念
哈希(Hash),又称散列,是一种将输入(键)通过哈希函数转换为固定长度输出(哈希值)的过程。这个输出通常是一个整数。哈希函数具有以下性质:
- 确定性:相同的输入必须产生相同的输出。
- 高效性:计算过程必须快速。
- 均匀性:理想情况下,不同的输入应均匀地映射到输出空间,减少冲突。
哈希最常见的应用是哈希表(Hash Table),它利用哈希值作为数组下标来存储数据,从而实现近乎常数时间的查找、插入和删除操作。
例如: 待插入数据集合为:{1, 7, 6, 4, 5, 9}; 哈希函数为:hash(key) = key % capacity; capacity 为存储元素底层空间总的大小。
capacity = 10, hash(1)= 1%10=1 hash(7)=7%10=7 hash(6)= 6%10= 6 hash(4)=4%10=4 hash(5)= 5%10=5 hash(9)= 9%10 =9
用该方法进行搜索不必进行多次关键码的比较,因此搜索的速度比较快,但当我们向集合中插入元素 44 时,会出现什么问题?元素 44 与元素 4 通过该哈希函数得到的哈希值是相同的,此时出现了哈希冲突!
哈希表数据结构
哈希表是一种根据键直接访问内存位置的数据结构。它由两个主要部分组成:
- 桶数组(Bucket Array):一块连续的内存空间,每个位置称为一个桶。
- 哈希函数:将键映射到桶的索引。
当我们插入一个键值对时,先计算键的哈希值,然后通过哈希函数得到桶的索引,将值存入该桶。查找时同样计算哈希值,直接定位到桶。
哈希函数
哈希函数的目标是让键均匀分布在桶中。常用的哈希函数有:
直接定址法
哈希函数为 H(key) = a*key + b,其中 a 和 b 为常数。适用于关键字分布基本连续的情况,可以避免冲突,但若关键字不连续,会造成空间浪费。 通常 a=1,b=0 是最简单的形式,即 H(key)=key;
- 优点:简单、不会产生冲突(如果关键字不重复),查找效率最高 O(1)。
- 缺点:要求关键字集合中的值连续且分布范围不大。如果关键字不连续(如 1, 100, 1000),会导致大量空位,浪费存储空间。
- 适用:适用于关键字分布基本连续且范围较小的静态集合,如学号从 2023001~2023100 的学生记录。
除留余数法
哈希函数为 H(key) = key % p,其中 p 通常为小于或等于表长的质数或素数。这种方法简单,适用范围广,但可能产生冲突,需要处理冲突。需要选择合适的 p 以减少冲突。
- 优点:计算简单,适用范围广,关键字可以是整数、字符串(先转换为整数)等。
- 缺点:会产生冲突(不同关键字映射到同一地址),需要配合冲突解决策略(如链地址法、开放地址法)。
- 适用:绝大多数哈希表实现采用此方法(如 C++ unordered_set/map 的哈希函数底层会结合其他混合算法,但基本思想基于取模)。


