我怎样才能改进自己的哈希映射的实现

时间:2012-01-16 08:45:18

标签: performance algorithm data-structures hashmap hashtable

出于学习目的,我正在编写自己的哈希映射实现。我使用separate chaining with list heads作为我的主题。

这就是结构的样子:

| 0   | ---> | 11 | ---> | 33 | ---> | -- | ---> | 121 | ---> | TAIL |
| 1   | ---> | 12 | ---> | 34 | ---> | -- | ---> | 122 | ---> | TAIL |
| -   |
| -   |
| -   |
| D-1 | ---> | -- | ---> | -- | ---> | -- | ---> | -- | ---> | TAIL |

这是一个链表的数组,其中,

D =数组的大小,

| 11 | =带键的元素; 11 AND元素按排序方式插入

算法:

void Insert(key, value):
 int bucket = hash_fn(key); // key % D, for now
 // accessing this bucket or array-index in array is O(1)
 // insert in linked list at the right position
 LL[bucket]->insert(new object(key, value))

bool Lookup(key):
 int bucket = hash_fn(key); // key % D, for now
 // search for key in LL[bucket]

关注:如果很多元素被映射到同一个桶,搜索将不会是O(1),事实上,它可能倾向于O(n)。

我该如何改善这个?

3 个答案:

答案 0 :(得分:2)

你做不到。这就是为什么通过使用一个好的哈希函数来防止这种情况发生的原因,这个哈希函数可以在桶上均匀地分布项目,并确保你使用足够的桶。

如果您愿意偏离带有链接列表的哈希表的想法,您可以尝试在存储桶中放置一些其他数据结构 - 例如某种自平衡树,如红色 - 黑色或AVL一个得到O(log(m))行为,其中m是每个桶的最大条目数。但那实际上并不会让你开心。只需使用好的哈希函数即可。

答案 1 :(得分:0)

来自wikipedia

  

具有良好的散列函数,平均查找成本几乎不变,因为负载因子从0增加到0.7(大约2/3满)左右。[引证需要]超过这一点,碰撞的概率和处理它们的成本增加了。

所以有了足够好的哈希函数和一个相当大的哈希表,你不应该关注它。

答案 2 :(得分:0)

您可以做的是Hashing with Chaining,它将使用链接列表来帮助避免哈希表中的冲突。
这将允许您的查找保持相当稳定,即使许多元素映射到相同的哈希桶。

但是,使用足够好的哈希函数,除非您希望哈希表接近容量,否则不必担心这一点。

This Wikipedia Article还包含一些关于此技术的非常好的信息。