真实面经题目 · 原创解析
哈希冲突中,伪随机开放地址法如何插入和查找元素?
伪随机开放地址法用同一个哈希表数组解决冲突,通过可复现的探测序列寻找空位或目标元素,关键是插入和查找使用相同序列。
真实面经题目 · 原创解析
伪随机开放地址法用同一个哈希表数组解决冲突,通过可复现的探测序列寻找空位或目标元素,关键是插入和查找使用相同序列。
开放地址法发生哈希冲突时,不再挂链表,而是在表内继续探测其他槽位。伪随机探测会根据 key 的哈希值和固定随机序列生成 h(key, 0), h(key, 1)...。插入时按序列找第一个空槽或可复用删除槽;查找时必须按同样序列查,直到找到目标 key,遇到从未使用过的空槽才可判定不存在。删除通常用 tombstone 标记,不能直接清空,否则会截断后续查找链。负载因子过高时探测变长,需要扩容。
开放地址法把所有元素都放在哈希表数组里。冲突后不使用外部链表,而是按某种探测规则寻找另一个槽位,因此表的空位分布和负载因子会直接影响查询成本。
伪随机开放地址法不是每次真正随机,而是为同一个 key 生成可复现的探测序列。插入和查找必须走完全一致的序列,否则已经写入表中的元素会沿另一条路径被跳过。
先计算初始哈希槽,如果被其他 key 占用,就依次尝试伪随机序列中的下一个槽位,直到遇到空槽或可复用的删除标记。插入成功后,key、value 和槽位状态要一起写入。
查找时也按同样序列探测。找到相同 key 就返回;遇到 tombstone 不能停止;只有遇到从未占用过的空槽,才说明目标不存在。
删除一般放 tombstone,避免破坏查找路径。随着负载因子升高,探测次数增加,需要扩容并重新哈希,保持查询性能,同时清理过多删除标记。
开放地址法冲突后仍在数组内探测,链地址法在桶后挂链表或其他结构;前者缓存友好但对负载因子更敏感。
直接置空会让查找在该槽位提前停止,导致后面通过冲突探测插入的元素无法被找到。
如果探测序列覆盖不好或负载因子过高,仍可能聚集和退化,需要设计序列并控制扩容。