我发现了这个简单的实现:
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)?
最佳答案
每个表条目都需要包含一组与散列匹配的键/值对。在查找表条目后,您需要在该集合中搜索请求的键。
如果碰撞很少见,那么一个简单的 vector 对可能就足够了。如果它们足够频繁以至于搜索速度太慢,并且您不能通过扩大表或使用更好的 has 函数来降低频率,那么请考虑对 vector 进行排序并使用二进制搜索,或使用 std::map
,或另一个哈希表(具有不同的哈希函数),用于存储碰撞元素。
当然,除非这是一个学习练习,否则您通常只使用 std::unordered_map
(或者如果您不能使用 C++11,则使用 Boost、TR1 或 STL 等价物库)。
此外,永远记住 Rule of Three在设计管理内存或其他资源的类时。如果有人试图复制您的类(class),您的类(class)将会大错特错。
关于c++ - C++中的哈希表实现避免和解决冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17658657/