how to search using double hash in c

寵の児 提交于 2019-12-25 02:57:49

问题


I have a server to receive request from multiple client. I have done this with threads. I want to insert some user name and password to hash table. For that I am using double hash method. It was inserted successfully. But I want to know when user enter a user name, I need to search on hash table whether this username already present. But I can't do it now. I know the concept like using hashing. Get the index using hashfunction1 through username and use double hash like this. But how can I write that code ?

My code:

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 
}

How can I write code to search a username is already present using double hashing from hash table in C? I think traverse whole hash table is not good practice ..is it?


回答1:


Your hashtable is of a fixed size S, so you can enter at most S elements.

The idea of the double hash with hash codes H1 and H2 is: If there is already an entry at position H1, traverse the hash width the stride H2. The size S is a prime. That means that with any stride H2 < S except H2 = 0, you will eventually visit all entries before coming full circle.

Of course, if you find an empty slot, you take it. In a sparsely populated hash, you usually have to go only a few steps from the original value to find an emty slot.

The more populated your hash gets, the less efficient the key search will be. One solution is to keep track of the number of elements and resize the hash to a bigger size when, say, more than 75% of entries are occupied. The new size must, of course, also be prime.

Also note these problems in your code: You might generate a hash value of 0 for the step size and if your hash table is full, your search for an empty slot will loop infinitely. It is also not necessary to pass the hash table by reference, because you never change the pointer itself, just its struct members. You can even make both key and htable const.

So:

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;
}

This code returns a special value -1 to indicate that there aren't any empty slots in the hash table.

If you want to look up a username, you use the same strategy. Here, you must additionally compare the key for each node, because different keys may share the same hash code. If you find an empty slot, the entry is not in the table.

This function returns a pointer to the user data (whose type I've named struct data; you don't show thze definition of the hash table struct) associated with the key or NULL if the user can't be found:

struct data *FindKey(const char *key, const struct HashTable *htable)
{    
    int hashVal, stepSize, startVal;

    hashVal = HashFunc1(key, htable->size);
    if (htable->table[hashVal].username == NULL) return NULL;
    if (strcmp(htable->table[hashval].username, key) == 0) {
        return &htable->table[hashVal];
    }

    startVal = hashVal;
    stepSize = HashFunc2(key, (*htable)->size - 1) + 1;

    for(;;)  {
        hashVal = (hashVal + stepSize) % htable->size;
        if (hashVal == startVal) return NULL;
        if (htable->table[hashVal].username == NULL) return NULL;
        if (strcmp(htable->table[hashval].username, key) == 0) {
            return &htable->table[hashVal];
        }
    }

    return NULL;
}

Caveat: I haven't tested this code, but I hope that you understand the basic working.



来源:https://stackoverflow.com/questions/30136328/how-to-search-using-double-hash-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!