【问题标题】:hash table : how to achieve 0(1)?哈希表:如何实现 0(1)?
【发布时间】:2014-05-27 17:38:26
【问题描述】:

上下文:

我在阅读 Pomakis 的哈希表实现时出现了一个问题。 Hash lookup

我经常使用 Startpage 来查找更多信息,但仍不清楚。

问题:

由于它使用链表来检索密钥,如何获得 0(1) 时间复杂度?

问题:

结构:

typedef struct KeyValuePair_struct {
    const void *key;
    void *value;
    struct KeyValuePair_struct *next;
} KeyValuePair;

对我来说,它看起来像一个链表。如果我错了,请纠正我。

void *HashTableGet(const HashTable *hashTable, const void *key) {
    long hashValue = hashTable->hashFunction(key) % hashTable->numOfBuckets;
    KeyValuePair *pair = hashTable->bucketArray[hashValue];

    while (pair != NULL && hashTable->keycmp(key, pair->key) != 0)
        pair = pair->next;

    return (pair == NULL)? NULL : pair->value;
}

我到处读到,要获取密钥,我们必须从结构链的开头迭代到正确的结构,因为我们事先不知道下一个结构的地址。

动态分配。

所以我不明白这一点:后一段代码似乎从链的开头迭代,但作者说它是 O(1)(他可能是对的,我对我的假设肯定是错误的它是 0(n) )。

我知道我错过了什么。但是什么?

谢谢

【问题讨论】:

  • 进入bucketO(1),但是一个bucket可能有多个entry。桶内的查找是线性的,是的。当桶数足够大,且元素分布均匀时,相当于O(1)。在只使用一个桶的病态情况下,它是O(N)

标签: c hash time-complexity


【解决方案1】:

函数HashTableGet()会先从数组中获取它的KeyValuePair

KeyValuePair *pair = hashTable->bucketArray[hashValue];

这个操作是O(1)

next 指针仅用于在添加新 KeyValuePair 时不同键产生相同哈希值的情况。然后下一个指针用于将该 KeyValuePair 存储在列表中。

检索时,如果键与第一个 KeyValuePair 键不匹配,则需要在列表中进行搜索。

while (pair != NULL && hashTable->keycmp(key, pair->key) != 0)
    pair = pair->next;

【讨论】:

  • 好的!所以最好的情况是 0(1),最坏的情况是 0(1) + 0(n),对吧?因此,在出现重复的情况下,一个好的散列对于最小化线性查找的重要性。对吗?
  • 是的,bucketArray 的大小也很重要。
猜你喜欢
  • 2016-03-25
  • 2011-10-14
  • 2011-09-15
  • 2012-06-03
  • 2021-09-14
  • 2013-05-31
  • 1970-01-01
  • 2016-05-17
相关资源
最近更新 更多