Skip to content

问题反馈:hash_map_open_addressing.js,线性探测解决哈希冲突,会产生无限循环。 #1728

Open
@yaomk

Description

@yaomk

问题描述

  • 先向哈希表尽可能多的添加数据,不触发扩容机制,然后删除这些数据,使得 TOMBSTONE 空桶尽可能的占满 buckets,然后执行添加操作。
  • 进入 findBucket(key) 方法,while (this.#buckets[index] !== null) 此时没有桶为 null,并且没有已存在 key 与添加的 key 相同,无法终止循环。

其他语言应该都能复现,已在 js,java 中复现。

可能的解决方法:

在扩容时,将 TOMBSTONE 的数量也算进去,这样的话,必定会有 null 的空桶。不过会导致空间浪费。😢

复现代码:

let hashmap = new HashMapOpenAddressing()
hashmap.put(0,'0')
hashmap.put(1,'0')
hashmap.put(2,'0')

// 此时,hashmap.#buckets为 [{key:0,val: '0'}, {key:1,val: '0'}, {key:2,val: '0'}, null]
hashmap.remove(0)
hashmap.remove(1)
hashmap.remove(2)
// 此时,hashmap.#buckets为 [{key:-1,val: '-1'}, {key:-1,val: '-1'}, {key:-1,val: '-1'}, null]

hashmap.put(3,'0')
// [{key:-1,val: '-1'}, {key:-1,val: '-1'}, {key:-1,val: '-1'}, {key:3,val: '0'}]
hashmap.put(7, '0') // 此时添加不触发扩容操作,继续执行 findBucket(key) 方法,进入无限循环。
// 理想情况下应该为 [{key:7,val: '0'}, {key:-1,val: '-1'}, {key:-1,val: '-1'}, {key:3,val: '0'}]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions