chapter_hashing/hash_collision/ #89
Replies: 107 comments 140 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.
-
大佬您好,请问链式地址插入元素那里,“再将结点(即键值对)添加到链表头部即可”,为什么要插入到头部呢?尾部不可以吗?插入到链表的尾部,不是保证链表的顺序与插入顺序一致吗? |
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.
-
最后一小节关于 JDK 1.8 中链表转红黑树的链表长度表述不准确。应该数组长度达到64(源码中是 <64)且链表长度超过 8,即元素个数达到 9 个时,才会转红黑树。文中链表长度达到 8 个是不对的 |
Beta Was this translation helpful? Give feedback.
-
在hash_map_open_addressing.java中在 findBucket 方法中,循环的跳出条件是遇到空桶 (buckets[index] == null)。然而,由于 TOMBSTONE 不计入 size,在哈希表大量使用删除标记后,表中可能会没有任何空桶,即所有桶都被占用或被标记为 TOMBSTONE。如果在这种情况下插入新的键值对,findBucket 将会一直循环,因为没有空桶供跳出。 |
Beta Was this translation helpful? Give feedback.
-
在hash_map_chaining.c添加操作 |
Beta Was this translation helpful? Give feedback.
-
在 hash_map_open_addressing.cpp 中: |
Beta Was this translation helpful? Give feedback.
-
first_tombstone = -1 |
Beta Was this translation helpful? Give feedback.
-
def find_bucket(self, key: int) -> int: |
Beta Was this translation helpful? Give feedback.
-
C++中的unordered_map采用的是链式地址 |
Beta Was this translation helpful? Give feedback.
-
hash_map_chaining.java 中打印哈希表方法会打印空集合,应该增加集合为空判断。 /* 打印哈希表 */
void print() {
for (List<Pair> bucket : buckets) {
if (!bucket.isEmpty()) {
List<String> res = new ArrayList<>();
for (Pair pair : bucket) {
res.add(pair.key + " -> " + pair.val);
}
System.out.println(res);
}
}
} |
Beta Was this translation helpful? Give feedback.
-
关于开放寻址,第一次看,看了好久≡(▔﹏▔)≡,我自己写的代码,标注很详细。各种情况我都考虑了,比如,先遇到空;没有遇到空,然后向下遍历,遇到空桶之前遇到0个,1个,或者更多个被标记为空桶的键值对。写的代码在这了,希望你看了能帮助到你( •̀ ω •́ )✧ 。
} /* 开放寻址 实现哈希表 */
} |
Beta Was this translation helpful? Give feedback.
-
day05 |
Beta Was this translation helpful? Give feedback.
-
C#简单hashtable namespace HashTable.Console;
public class Map<TKey, TValue>
{
private readonly KeyValuePair<TKey, TValue>[] _buckets = new KeyValuePair<TKey, TValue>[100];
private int _count;
public int Capacity => _buckets.Length;
public int Count => _count;
public TKey[] Keys => GetKeys();
public TValue[] Values => GetValues();
public void Put(TKey key, TValue value)
{
var index = GetIndex(key);
_buckets[index] = new KeyValuePair<TKey, TValue>(key, value);
_count++;
}
public void Remove(TKey key)
{
var index = GetIndex(key);
_buckets[index] = null!;
_count--;
}
public TValue Get(TKey key)
{
var index = GetIndex(key);
return _buckets[index].Value;
}
private TKey[] GetKeys()
{
var res = _buckets.Where(x => x is not null).Select(x => x.Key).ToArray();
return res;
}
private TValue[] GetValues()
{
var res = _buckets.Where(x => x is not null).Select(x => x.Value).ToArray();
return res;
}
private int GetIndex(TKey key)
{
if (key is null)
throw new ArgumentNullException(nameof(key));
var hashCode = key.GetHashCode() & Int32.MaxValue;
var index = hashCode % Capacity;
return index;
}
} |
Beta Was this translation helpful? Give feedback.
-
C++ 链式地址哈希表 #pragma once
#include <vector>
#include <functional>
#include <stdexcept>
template<typename K, typename V>
class HashMap
{
private:
struct HashNode
{
K key;
V value;
HashNode *next;
HashNode(const K &k, const V &v) : key(k), value(v), next(nullptr){}
};
std::vector<HashNode *> table;
int capacity;
int size;
const double LOAD_FACTOR = 0.75;
int hashFunc(const K &key)
{
std::hash<K> hasher;
return hasher(key) % capacity;
}
public:
HashMap(int initCapacity = 11) : capacity(initCapacity), size(0)
{
table.resize(capacity, nullptr);
}
~HashMap()
{
for(int i = 0; i < capacity; ++i)
{
HashNode *entry = table[i];
while (entry)
{
HashNode *prev = entry;
entry = entry->next;
delete prev;
}
}
}
void put(const K &key, const V &val)
{
if(static_cast<double>(size) / capacity >= LOAD_FACTOR)
{
resize();
}
int index = hashFunc(key);
HashNode *entry = table[index];
if(!entry)
{
table[index] = new HashNode(key, val);
size++;
return;
}
HashNode *prev = nullptr;
while (entry)
{
if(entry->key == key)
{
entry->value = val;
return;
}
prev = entry;
entry = entry->next;
}
prev->next = new HashNode(key, val);
size++;
}
void resize()
{
int oldCapacity = capacity;
capacity = oldCapacity * 2 + 1;
std::vector<HashNode *> newTable(capacity, nullptr);
for (int i = 0; i < oldCapacity; ++i)
{
HashNode *entry = table[i];
while (entry)
{
HashNode *next = entry->next;
int newIndex = hashFunc(entry->key);
entry->next = newTable[newIndex];
newTable[newIndex] = entry;
entry = next;
}
table[i] = nullptr;
}
table = std::move(newTable);
}
V get(const K &key)
{
int index = hashFunc(key);
HashNode *entry = table[index];
while (entry)
{
if (entry->key == key)
{
return entry->value;
}
entry = entry->next;
}
throw std::runtime_error("Key not found");
}
void remove(const K &key)
{
int index = hashFunc(key);
HashNode *entry = table[index];
HashNode *prev = nullptr;
while (entry)
{
if (entry->key == key)
{
if (!prev)
{
table[index] = entry->next;
}
else
{
prev->next = entry->next;
}
delete entry;
size--;
return;
}
prev = entry;
entry = entry->next;
}
throw std::runtime_error("Key not found");
}
}; |
Beta Was this translation helpful? Give feedback.
-
开放寻址的这个函数 |
Beta Was this translation helpful? Give feedback.
-
基于链表的链式地址(python版)
class hashLinkedList:
class HashMapChaining:
|
Beta Was this translation helpful? Give feedback.
-
这里没看懂啥意思,感觉奇奇怪怪,后续再来看吧 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
chapter_hashing/hash_collision/
动画图解、一键运行的数据结构与算法教程
https://www.hello-algo.com/chapter_hashing/hash_collision/
Beta Was this translation helpful? Give feedback.
All reactions