我有一台服务器接收来自多个客户端的请求。我用线程完成了这个。我想在哈希表中插入一些用户名和密码。为此,我使用双哈希方法。它已成功插入。但我想知道当用户输入用户名时,我需要在哈希表上搜索该用户名是否已经存在。但我现在不能这样做。我知道像使用哈希这样的概念。使用hashfunction1通过用户名获取索引并使用像这样的双重哈希。但是我该如何编写该代码呢?
我的代码:
int HashFunc1 (char *key,int size)
{
int i = 0,value = 0;
for(i = 0 ; key[i] != '\0'; i++)
{
value += ( key[i] + ( i + 1 ) );
}
return value % size;
}
int HashFunc2 (char *key,int size)
{
int i = 0,value = 0;
for(i = 0; key[i] != '\0'; i++)
{
value += ( key[i] + ( i + 1 ) );
}
return (value * size - 1) % size;
}
int Findindex(char *key,struct HashTable **htable)
{
int hashVal = 0,
stepSize = 0;
hashVal = HashFunc1(key, (*htable)->size);
stepSize= HashFunc2(key, (*htable)->size);
/*to avoid collisions)*/
while ( (*htable)->table[hashVal].username != NULL)
{
/*double hahsing process*/
hashVal = hashVal + stepSize;
hashVal = hashVal % (*htable)->size;
}
return hashVal;
}
int insert_to_hashtable(char *key,char *password,struct HashTable **htable)
{
int pos = 0;
/*find the index to insert new user datas*/
pos = Findindex(key,htable);
//code to insert to coresponding data if this empty
}
如何使用C中哈希表的双哈希来编写用于搜索用户名的代码?我认为遍历整个哈希表不是很好的做法..是吗?
答案 0 :(得分:1)
您的哈希表具有固定大小S,因此您最多可以输入S个元素。
哈希码H1和H2的双重哈希的想法是:如果在位置H1处已存在条目,则遍历步幅H2的哈希宽度。大小S是素数。这意味着任何步幅H2<除了H2 = 0之外,你最终会在完整的圈子之前访问所有参赛作品。
当然,如果你找到一个空槽,你可以拿走它。在稀疏填充的散列中,您通常只需要从原始值开始几步即可找到一个emty插槽。
您的哈希填充越多,密钥搜索的效率就越低。一种解决方案是跟踪元素的数量并将哈希值调整为更大的大小,例如,超过75%的条目被占用。当然,新尺寸也必须是最重要的。
还要注意代码中的这些问题:您可能会为步长生成哈希值0,如果哈希表已满,则搜索空槽将无限循环。也没有必要通过引用传递哈希表,因为您永远不会更改指针本身,只更改其结构成员。您甚至可以同时制作key
和htable
const
。
所以:
int Findindex(const char *key, const struct HashTable *htable)
{
int hashVal, stepSize, startVal;
hashVal = HashFunc1(key, htable->size);
if (htable->table[hashVal].username == NULL) return hashVal;
startVal = hashVal;
stepSize = HashFunc2(key, (*htable)->size - 1) + 1;
do {
hashVal = (hashVal + stepSize) % htable->size;
if (hashVal == startVal) return -1;
} while (htable->table[hashVal].username);
return hashVal;
}
此代码返回一个特殊值-1,表示哈希表中没有任何空槽。
如果要查找用户名,请使用相同的策略。在这里,您还必须比较每个节点的密钥,因为不同的密钥可能共享相同的哈希代码。如果找到一个空槽,则该条目不在表中。
此函数返回一个指向用户数据的指针(其类型名称为struct data
;您不显示与该键相关联的哈希表结构的定义)或{{1如果无法找到用户:
NULL
警告:我还没有测试过这段代码,但我希望你能理解基本的工作。