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