【问题标题】:Hash table implementation collision avoidance and resolution in C++C ++中的哈希表实现冲突避免和解决
【发布时间】:2013-07-15 16:03:43
【问题描述】:

我发现了这个简单的实现:

http://www.onextrabit.com/view/502c152965e7d250c5000001

但是它没有任何共谋避免。所以我把它修改成这样:

#include <iostream>
#include <sstream>

using namespace std;

template <typename ElemType>
class HashTable {
private:
    // data
    ElemType* hashData;
    // hash table size
    int tableSize;
    // djb2 hash function
    int hashing(string key) {
        int hash = 5381;

        for (int i = 0; i < key.length(); i++)
            hash = ((hash << 5) + hash) + (int)key[i];

        return hash % tableSize;
    }

public:
    HashTable(int size) {
        tableSize = size;

        // init hash table data given table size
        hashData = new ElemType[tableSize];
    }

    ~HashTable() {
        delete[] hashData;
    }

    void set(string key, const ElemType& value) {
        int index = hashing(key);
        int i = 0;
        for (;(hashData[index] != (ElemType)NULL) && (i <= tableSize); i++) {
            index = (index + 1) % tableSize;
        }
        if (i > tableSize) {
            cout << "No empty bucket!" << endl;
            return ;
        }
        hashData[index] = value;
    }

    string get(string key) {
        int index = hashing(key);
        stringstream result;
        result << hashData[index];
        int i = 0;
        for (;(hashData[++index] != (ElemType)NULL) && (i <= tableSize); i++) {
            result << " or " << hashData[index];
            index %= tableSize;
        }
        return result.str();
    }
};

int main() {

    HashTable<int> hash(50);

    hash.set("Hello", 12);
    hash.set("World", 22);
    hash.set("Wofh", 25);
    for (int i = 1; i < 10; i++) {
        hash.set("Wofh", i);
    }

    cout << "Hello " << hash.get("Hello") << endl;
    cout << "World " << hash.get("World") << endl;
    cout << "Wofh " << hash.get("Wofh") << endl;
    return 0;
}

这是我第一次实现哈希表。现在 "World" 和 "Wofh" 从 hashing() 函数得到相同的结果。很显然,这是在勾结。但是,当我想检索“世界”时,它会显示所有串通的值。我的问题是有没有办法只使用线性探测来显示“世界”数字(即 22)?

【问题讨论】:

  • 为什么不直接使用 C++11 中的 unordered_map 或 boost?
  • @Mark 这是一个实施问题

标签: c++ hash hashtable implementation


【解决方案1】:

每个表条目都需要包含一组与哈希匹配的键/值对。然后,您需要在查找表条目后在该集合中搜索请求的键。

如果冲突很少见,那么简单的对向量可能就足够了。如果它们足够频繁以至于搜索太慢,并且您无法通过扩大表或使用更好的 has 函数来降低频率,则考虑对向量进行排序并使用二进制搜索,或使用 std::map 或其他哈希表(具有不同的哈希函数),用于存储碰撞元素。

当然,除非这是一个学习练习,否则您通常只使用std::unordered_map(或者如果您不能使用 C++11 库,则使用 Boost、TR1 或 STL 等价物)。

另外,在设计管理内存或其他资源的类时,请始终记住Rule of Three。如果有人试图复制你的课程,你的课程会大错特错。

【讨论】:

  • 我不太明白这个答案。能不能多提供一些算法示例?
  • @user1292095:我不知道如何让我的答案更清楚,但good book(甚至Wikipedia)应该会告诉你关于哈希表你需要知道的一切。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-01
  • 1970-01-01
  • 2010-09-11
  • 2011-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多