8 条题解
-
0
给我简单讲解:哈希冲突(Hash Collision)的开地址法(线性探测与二次探测)
在 CSP-J/S 初赛和各省名校自招中,“哈希冲突(Hash Collision)的开地址法(线性探测与二次探测)” 是每年必考、且只要考就属于 100% 拿分的送分题。
这类题目不需要写代码,关键在于搞懂探测公式,并在草稿纸上模拟画表格。
一、 核心背景:什么是哈希冲突?
- 假设我们有一个长度为 的哈希表(数组下标 )。
- 散列函数通常是模运算:。
- 冲突:两个不同的数算出来的下标一样(比如 , 和 ,因为 ,它们都想挤进下标
1的位置)。 - 开地址法(Open Addressing):既然原本的家被占了,就按照某种“既定规则”在数组里找下一个空位置。
二、 线性探测法(Linear Probing)——“挨个往后挪”
1. 核心公式
如果算出来的初始位置 已经有人了,就依次往后看:
$$H_i = (H(key) + i) \bmod M \quad (i = 1, 2, 3, \dots) $$通俗说就是:+1,+2,+3,+4……挨个往后找,走到数组末尾就绕回开头(取模)。
2. 手推实战演练
题目:散列表长 ,。采用线性探测法,依次插入
{12, 23, 34}。求34最终落在哪个位置?我们画一个下标 的表格:
- 插入 12:。下标
1是空的,直接放入:- 表格:
位置 1: 12
- 表格:
- 插入 23:。发现下标
1已经被12占了(冲突)!- 启动线性探测:试探 。
- 下标
2是空的,放入: - 表格:
位置 1: 12,位置 2: 23
- 插入 34:。下标
1冲突!- 试探 ,也被
23占了,继续冲突! - 试探 ,下标
3是空的,成功放入! - 结果:
34最终存放在下标 3。
- 试探 ,也被
- 优缺点常考点:容易产生**“聚集/堆积(Clustering)”**现象——连续一长串都被占满,后面的数冲突越来越频繁。
三、 二次探测法(Quadratic Probing)——“跳跃着找”
为了解决线性探测“容易扎堆”的问题,二次探测改成了步长平方跳跃(有的教材也叫平方法)。
1. 核心公式
如果 冲突,探测序列为:
$$H_i = (H(key) \pm i^2) \bmod M \quad (i = 1, 2, 3, \dots) $$即偏移量依次为:
$$+1^2, \ -1^2, \ +2^2, \ -2^2, \ +3^2, \ -3^2, \dots $$也就是:
⚠️ 草稿纸算负数取模秘诀(极其重要,考场避坑点): 如果算出来是负数,直接加上表长 即可! 例如:。
2. 手推实战演练
题目:散列表长 ,。采用二次探测法,依次插入
{12, 23, 34}。求34最终落在哪个位置?- 插入 12:,下标
1空闲,存入1。 - 插入 23:,冲突!
- 探测第一步():,下标
2空闲,存入2。
- 探测第一步():,下标
- 插入 34:,冲突!
- 探测第一步():,位置
2已被23占领,继续冲突! - 探测第二步():!
- 下标
0是空的,成功放入! - 结果:
34最终存放在下标 0(注意与线性探测得到的结果不同!)。
- 探测第一步():,位置
四、 考场应试“三步做题法”
初赛或自招考场上遇到这类选择题,不要在脑子里凭空想,按以下 3 步做:
- 画尺子:草稿纸画一条横线,标出下标 。
- 算模数:把每一个给出的数先模上 ,写在草稿纸上。
- 按顺序落子:
- 没冲突直接填进去;
- 遇到冲突看清题干:
- 若是线性:
+1, +2, +3...顺延往后走; - 若是二次:先试
+1,不行试-1,再不行试+4,再不行试-4……(负数直接加模数 )。
- 若是线性:
信息
- ID
- 19505
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者