用线性探测解决哈希冲突时,几个对象可能沿着同一条探测路径连续存放。删除中间项如果立即标成从未使用的空位,后面的对象可能再也查不到。
表长十一,编号除以十一的余数为起点,随后逐格前进并循环。查找遇到真正空位才停止,墓碑则继续;插入记住遇到的第一个墓碑,但仍要继续检查是否已存在相同编号,再决定落点。
本例的输入和输出
add为插入、remove为删除、find为查询。None为真正空位,负一为墓碑,其他数字为对象编号。
事件 | 检查位置顺序 | 结果 | 十一个槽位 ['add', 3] | [3] | 插入 | [None, None, None, 3, None, None, None, None, None, None, None] ['add', 14] | [3, 4] | 插入 | [None, None, None, 3, 14, None, None, None, None, None, None] ['add', 25] | [3, 4, 5] | 插入 | [None, None, None, 3, 14, 25, None, None, None, None, None] ['remove', 14] | [3, 4] | 删除 | [None, None, None, 3, -1, 25, None, None, None, None, None] ['find', 25] | [3, 4, 5] | 找到 | [None, None, None, 3, -1, 25, None, None, None, None, None] ['add', 36] | [3, 4, 5, 6] | 插入 | [None, None, None, 3, 36, 25, None, None, None, None, None] ['remove', 69] | [3, 4, 5, 6] | 不存在 | [None, None, None, 3, 36, 25, None, None, None, None, None] ['remove', 30] | [8] | 不存在 | [None, None, None, 3, 36, 25, None, None, None, None, None] ['find', 25] | [3, 4, 5] | 找到 | [None, None, None, 3, 36, 25, None, None, None, None, None] ['find', 36] | [3, 4] | 找到 | [None, None, None, 3, 36, 25, None, None, None, None, None] ['remove', 69] | [3, 4, 5, 6] | 不存在 | [None, None, None, 3, 36, 25, None, None, None, None, None] ['find', 58] | [3, 4, 5, 6] | 不存在 | [None, None, None, 3, 36, 25, None, None, None, None, None] ['remove', 25] | [3, 4, 5] | 删除 | [None, None, None, 3, 36, -1, None, None, None, None, None] ['remove', 78] | [1] | 不存在 | [None, None, None, 3, 36, -1, None, None, None, None, None] ['add', 42] | [9] | 插入 | [None, None, None, 3, 36, -1, None, None, None, 42, None] ['add', 78] | [1] | 插入 | [None, 78, None, 3, 36, -1, None, None, None, 42, None] ['remove', 78] | [1] | 删除 | [None, -1, None, 3, 36, -1, None, None, None, 42, None] ['remove', 78] | [1, 2] | 不存在 | [None, -1, None, 3, 36, -1, None, None, None, 42, None] ['find', 25] | [3, 4, 5, 6] | 不存在 | [None, -1, None, 3, 36, -1, None, None, None, 42, None] ['find', 17] | [6] | 不存在 | [None, -1, None, 3, 36, -1, None, None, None, 42, None] ['find', 17] | [6] | 不存在 | [None, -1, None, 3, 36, -1, None, None, None, 42, None]
表格中的编号只标识当前例子的元素,不应把对象身份、数组下标与计算数值混为一谈。阅读时先核对输入和边界,再沿记录检查每一步;空结果表示规则下没有可用项,并不是默认返回数值零。
复核与适用条件
墓碑不代表对象还存在,只代表这条探测链不能在这里提前结束。表格列出每次实际检查的位置、结果和完整表状态;满表没有空位或墓碑时插入失败,但已有对象的查找仍要正确。
这是一个固定容量、单线程的演算模型,没有扩容和并发写入。墓碑过多会让查找变长,实际实现可能需要整理或重建,但整理过程也必须保留所有真实对象及其查询结果。
练习时先独立复算一小段,再检查整体结果是否满足文中条件。遇到差异应保留中间记录并定位第一处不一致,而不是只调整最后答案。更换输入或操作规则后,需要重新计算,原记录只对这一例负责。
