chapter_hashing/hash_collision/ #89
Replies: 72 comments 117 replies
-
大佬,为什么这一页看不见图啊。 |
Beta Was this translation helpful? Give feedback.
-
而实际上,往往存在不同 key 对应相同 value 的情况, 这里的描述是不是容易引起歧义,应该是不同的key会产生相同的哈希值,而导致出现的问题 |
Beta Was this translation helpful? Give feedback.
-
大佬你好,我不理解为什么哈希扩容也能解决哈希冲突。 |
Beta Was this translation helpful? Give feedback.
-
你好,冲突处理这一块没有代码实现吗?只需要知道这个结论就好了吗 |
Beta Was this translation helpful? Give feedback.
-
大佬您好,请问链式地址插入元素那里,“再将结点(即键值对)添加到链表头部即可”,为什么要插入到头部呢?尾部不可以吗?插入到链表的尾部,不是保证链表的顺序与插入顺序一致吗? |
Beta Was this translation helpful? Give feedback.
-
你好,线性探测中:“查找元素:若出现哈希冲突“。这里没太明白查找元素的时候怎么会出现冲突呢? 输入一个key哈希函数的结果不是只有一个吗?!是插入的时候会把数组(桶)中已存在的的key的hash结果缓存,然后查找的时候先对比有冲突吗? |
Beta Was this translation helpful? Give feedback.
-
请问哈希函数一般怎么设计,比如多次哈希方法中,每个函数有什么设计思路嘛?会不会遇到一个插入操作,针对这个key所有哈希函数都冲突了情况呢? |
Beta Was this translation helpful? Give feedback.
-
开头可以简单补充一下什么是桶,要不萌新很迷惑,我就是萌新。谢谢大佬 |
Beta Was this translation helpful? Give feedback.
-
大佬好(●'◡'●)。请问多次哈希应该也会有不能直接删除元素的缺陷吧?另外对于标记已删除的空间,这个空间还能再次使用吗? |
Beta Was this translation helpful? Give feedback.
-
线性探测标志位是指DEFUNCT object吗?后续会更新Cockoo Hashing吗,这个也挺常见的。 |
Beta Was this translation helpful? Give feedback.
-
请问在“hash_map_chaining.cpp”中的remove函数中:
之所以需要第一行和第三行的原因是不是因为vector在创建的时候是申请的动态内存?所以在这里需要delete掉,对于STL不是很熟悉,希望能得到解答 |
Beta Was this translation helpful? Give feedback.
-
链式地址哈希表 扩容部分没懂 标记一下下次看 |
Beta Was this translation helpful? Give feedback.
-
HashMapChaining 的扩容方法 extend 好像有点问题,似乎没有考虑到相同 key 在扩容后对应的实际 index 会发生改变 |
Beta Was this translation helpful? Give feedback.
-
请问在 “hash_map_chaining.cpp” 的 extend() 函数中为什么将键值对从原哈希表搬运至新哈希表需要delete pair,这里的pair不是属于临时哈希表中的数据吗,它难道不是随代码块持续性的嘛,不太懂这个。 |
Beta Was this translation helpful? Give feedback.
-
hash_map_chaining 中 extend函数在每一个桶的链表循环中要释放内存,但在put函数中为什么不需要了?Node *cur = hashMap->buckets[index]; |
Beta Was this translation helpful? Give feedback.
-
pair->val = (char *)malloc(sizeof(strlen(val) + 1)); |
Beta Was this translation helpful? Give feedback.
-
链式地址中print好像没判断是否包含键值对,[]也会被打印 |
Beta Was this translation helpful? Give feedback.
-
作者您好,在链式地址中的负载因子计算,使用size/capacity,这里的capacity定义是桶数组数量是否合理?假设capacity是4,那么在一个桶中扎堆挂了四个链节点也会导致扩容,而另外三个桶其实是空着的。 |
Beta Was this translation helpful? Give feedback.
-
大佬你好,golang溢出桶过多时会触发等量扩容,怎么保证紧凑排列后溢出桶个数一定小于再次等量扩容的条件呢,如果有桶个数无穷大,某个哈希对应的bucket存满,溢出桶也存满超出2^15个 |
Beta Was this translation helpful? Give feedback.
-
线性探测部分,Go代码的put方法中,如果遇到带有删除标记的桶就插入键值,存在一种情况,即相同的键可能已经存在于该被删除桶位置之后。这种情况下,如果不继续探测以确认该键是否已存在于哈希表中,就可能会导致重复键的插入,造成空间浪费。 // 若遇到空桶、或带有删除标记的桶,则将键值对放入该桶
if m.buckets[j] == (pair{}) || m.buckets[j] == m.removed {
m.buckets[j] = pair{
key: key,
val: val,
}
m.size += 1
return
} 测试代码 func main() {
m := newHashMapOpenAddressing()
m.put(0, "a")
m.put(4, "b")
m.put(8, "c")
m.remove(4)
m.put(8, "d")
m.print()
}
优化之后的代码 func (m *hashMapOpenAddressing) put(key int, val string) {
if m.loadFactor() > m.loadThres {
m.extend()
}
idx := m.hashFunc(key)
firstRemovedIdx := -1 // 记录首次遇到的被删除桶的索引,初始化为-1表示未找到
for i := 0; i < m.capacity; i++ {
j := (idx + i) % m.capacity
// 如果是空桶,检查是否有遇到过被删除的桶
if m.buckets[j] == (pair{}) {
// 如果有,则在首次遇到的被删除的桶位置插入
if firstRemovedIdx != -1 {
j = firstRemovedIdx
}
m.buckets[j] = pair{key: key, val: val}
m.size++
return
} else if m.buckets[j].key == key && m.buckets[j] != m.removed {
// 如果找到相同的键且不是被删除的,更新值
m.buckets[j].val = val
return
} else if m.buckets[j] == m.removed && firstRemovedIdx == -1 {
// 如果是被删除的桶且是首次遇到,记录索引
firstRemovedIdx = j
}
}
}
|
Beta Was this translation helpful? Give feedback.
-
发现了一个小bug int main()
{
HashMapOpenAddressing hoa; // 默认4个位置
hoa.put(0, "0"); hoa.remove(0);
hoa.put(1, "1"); hoa.remove(1);
hoa.put(2, "2"); hoa.remove(2);
hoa.put(3, "3"); hoa.remove(3);
// 四个 "TOMBSTONE" 在 buckets 中
hoa.print();
// forever in findBucket()
hoa.get(0);
return 0;
}
|
Beta Was this translation helpful? Give feedback.
-
为啥java开放寻址的查询操作没有做线性探测 |
Beta Was this translation helpful? Give feedback.
-
对本小白来说有些晦涩难懂😭我先看看书再回来 |
Beta Was this translation helpful? Give feedback.
-
您好,线性探测的目的是给键值对找个空桶放入吧?那js代码里添加键值对为什么是覆盖之前的呢? |
Beta Was this translation helpful? Give feedback.
-
链式hash C代码有个疑问(不确定是不是我理解错了): |
Beta Was this translation helpful? Give feedback.
-
K大,有个理解问题,如图6-7,和上面的描述“删除元素会在数组内产生一个空桶 None”, |
Beta Was this translation helpful? Give feedback.
-
线性寻址哈希表在扩容时,被标记为TOMBSTONE的空位应该一起搬过去吧,不然每次扩容都相当于恢复初始状态,寻址的效率和空间利用率都会变低 |
Beta Was this translation helpful? Give feedback.
-
/* 删除操作 */ |
Beta Was this translation helpful? Give feedback.
-
chapter_hashing/hash_collision/
动画图解、一键运行的数据结构与算法教程
https://www.hello-algo.com/chapter_hashing/hash_collision/
Beta Was this translation helpful? Give feedback.
All reactions