Simple hash table implementation of C language

Source: Internet
Author: User
Tags shallow copy strcmp intel core i7

A simple hash table implementation
    • A simple hash table implementation
      • Principle
      • Definitions of hash tables and node data structures
      • Initializing and releasing a hash table
      • Hash hashing algorithm
      • Auxiliary function StrDup
      • Inserting and modifying a hash table
      • Find in hash table
      • The removal of the hash TABLE element
      • Hash table Printing
      • Test it.

This is an implementation of a simple hash table, c made in language.

Principle

Let's talk about the principle.
First there is an bucket array, the so-called bucket.

A hash table is characterized by its presence in the 数据 table 相关性 , which is related, where the data should be computed.

This hash table is the data that is used to store some key-value pair ( key -- value ) relationships, which key is its index in the table, and value is the accompanying data.

By hashing the string key into a bucket, the algorithm is deterministic, that is, one necessarily corresponds to the other key bucket .

Then there is the collision problem, which means that there are multiple key corresponding index values. For example: There are three key :, key1 the key3 key5 index value obtained by the hash algorithm is, that is keyToIndex 2 , these three key produced a collision, for the collision processing, is to use linked list, and not to re-hash.

This is the header file that contains

#include <stdio.h>#include <stdlib.h>#include <string.h>#define BUCKETCOUNT 16
Definitions of hash tables and node data structures
struct hashEntry{    const char* key;    char* value;    struct hashEntry* next;};typedef struct hashEntry entry;struct hashTable{    entry bucket[BUCKETCOUNT];  //先默认定义16个桶};typedef struct hashTable table;
Initializing and releasing a hash table
//初始化哈希表void initHashTable(table* t){    int i;    if (t == NULL)return;    for (i = 0; i < BUCKETCOUNT; ++i) {        t->bucket[i].key = NULL;        t->bucket[i].value = NULL;        t->bucket[i].next = NULL;    }}//释放哈希表void freeHashTable(table* t){    int i;    entry* e,*ep;    if (t == NULL)return;    for (i = 0; i<BUCKETCOUNT; ++i) {        e = &(t->bucket[i]);        while (e->next != NULL) {            ep = e->next;            e->next = ep->next;            free(ep->key);            free(ep->value);            free(ep);        }    }}
Hash hashing algorithm
//哈希散列方法函数int keyToIndex(const char* key){    int index , len , i;    if (key == NULL)return -1;    len = strlen(key);    index = (int)key[0];    for (i = 1; i<len; ++i) {        index *= 1103515245 + (int)key[i];    }    index >>= 27;    index &= (BUCKETCOUNT - 1);    return index;}
Auxiliary function StrDup

This is a more redundant approach because string.h there are a number of such functions in the C standard library.

//在堆上分配足以保存str的内存//并拷贝str内容到新分配位置char* strDup(const char* str){    int len;    char* ret;    if (str == NULL)return NULL;    len = strlen(str);    ret = (char*)malloc(len + 1);    if (ret != NULL) {        memcpy(ret , str , len);        ret[len] = ‘\0‘;    }    return ret;}

string.hThe related functions in

       #include <string.h>       char *strdup(const char *s);       char *strndup(const char *s, size_t n);       char *strdupa(const char *s);       char *strndupa(const char *s, size_t n);
Inserting and modifying a hash table

This is the insertion and modification is a method, if it key already exists in the hash table, then it is modified value , otherwise it is to insert a node.

Insert data into the hash table int Insertentry (table* t, const char* key, const char* value) {int index, VLEN1, vlen2;    entry* e, *ep;    if (t = = NULL | | key = NULL | | value = NULL) {return-1;    } index = Keytoindex (key);        if (T->bucket[index].key = = NULL) {T->bucket[index].key = StrDup (key);    T->bucket[index].value = StrDup (value);        } else {e = EP = & (T->bucket[index]); while (E! = NULL) {/////strcmp (E->key, key) = = 0) {//Find key, replace value VL                EN1 = strlen (value);                Vlen2 = strlen (E->value);                    if (Vlen1 > Vlen2) {free (e->value);                E->value = (char*) malloc (vlen1 + 1);                } memcpy (E->value, value, Vlen1 + 1);   return index;            Insert completed} EP = e;        E = e->next; }//End while (e ...//not found in current bucket//Create entry Join E = (entry*) malloc (sizeof (entry));        E->key = StrDup (key);        E->value = StrDup (value);        E->next = NULL;    Ep->next = e; } return index;
Find in hash table

Because the hash table is saved 键值对 , this method looks for the corresponding one from the hash table key value . Note that the address returned here value should not be modified for the data it points to, or it might happen unexpectedly.

//在哈希表中查找key对应的value//找到了返回value的地址,没找到返回NULLconst char* findValueByKey(const table* t , const char* key){    int index;    const entry* e;    if (t == NULL || key == NULL) {        return NULL;    }    index = keyToIndex(key);    e = &(t->bucket[index]);    if (e->key == NULL) return NULL;//这个桶还没有元素    while (e != NULL) {        if (0 == strcmp(key , e->key)) {            return e->value;    //找到了,返回值        }        e = e->next;    }    return NULL;}
The removal of the hash TABLE element

This function is used to remove the corresponding node in the hash table key , if it does not exist, then return NULL . If it exists, it returns the address of the node. Note that this does not release the node, and if it is not needed, it should be released manually.

Finding the key corresponding to the entry//in the hash table finds the return entry and removes it from the hash table//not found return nullentry* removeentry (table* T, char* key) {int index;   entry* E,*ep;    When searching, use the EP as the return value if (t = = NULL | | key = = NULL) {return null;    } index = Keytoindex (key);    E = & (T->bucket[index]); while (E! = NULL) {if (0 = = strcmp (key, E->key)) {//If the bucket is the first if (E = = & (T->bucke                T[index]) {//If the bucket has two or more elements//exchange First and second, then remove the second EP = e->next;                    if (ep = NULL) {entry TMP = *E;//Make a shallow copy exchange *e = *ep;//equivalent to the head node of the linked list has been removed  *EP = tmp;                This is the removed list header node Ep->next = NULL;                    } else {//This bucket is only the first element of EP = (entry*) malloc (sizeof (entry));                    *ep = *e;                    E->key = E->value = NULL;                E->next = NULL; }} else {//If it is not the first element of the bucket//Find its previous (this is the superfluous operation caused by poor design) EP = & (T->bucket[index]);                while (ep->next! = e) EP = ep->next;                Take e from it ep->next = e->next;                E->next = NULL;            EP = e;        } return EP;    }//End If (strcmp ... e = e->next; } return NULL;
Hash table Printing

This function is used to print the contents of a hash table.

void printTable(table* t){    int i;    entry* e;    if (t == NULL)return;    for (i = 0; i<BUCKETCOUNT; ++i) {        printf("\nbucket[%d]:\n" , i);        e = &(t->bucket[i]);        while (e->key != NULL) {            printf("\t%s\t=\t%s\n" , e->key , e->value);            if (e->next == NULL)break;            e = e->next;        }    }}
Test it.

The data used for testing comes from native-related information.

int main () {table T;    InitHashTable (&t);    Insertentry (&t, "Computer model", "ASUS X550JK notebook computer");    Insertentry (&t, "Operating system", "Windows 8.1 64-bit (DirectX 11)");    Insertentry (&t, "Processor", "Intel Core I7-4710HQ @ 2.50GHz four core");    Insertentry (&t, "motherboard", "ASUS X550JK (Intel Haswell)");    Insertentry (&t, "Memory", "4 GB (Hynix/hyundai)");    Insertentry (&t, "Master HDD", "Hitachi HGST hts541010a9e680 (1 tb/5400 rpm)");    Insertentry (&t, "graphics card", "NVIDIA GeForce GTX 850M (2 GB/asus)");    Insertentry (&t, "display", "Chi Mei Cmn15c4 (15.3 inch)");    Insertentry (&t, "Optical drive", "Panasonic Dvd-ram uj8e2 S DVD burner");    Insertentry (&t, "sound card", "Conexant smartaudio HD @ Intel Lynx Point High Fidelity Audio");    Insertentry (&t, "network card", "Realtek rtl8168/8111/8112 Gigabit Ethernet Controller/asus");    Insertentry (&t, "motherboard model", "Asus X550JK");    Insertentry (&t, "chipset", "Intel Haswell");    Insertentry (&t, "BIOS", "x550jk.301");   Insertentry (&t, "date of manufacture", "06/26/2014"); Insertentry (&t, "Master", "Is Me");    Insertentry (&t, "price", "60-sheet Red Chairman");    Insertentry (&t, "main hard Disk", "Change a 120G Solid state");    entry* e = removeentry (&t, "motherboard model");        if (E! = NULL) {puts ("to be released after finding");        Free (E->key);        Free (e->value);        Free (e);    e = NULL;    } printtable (&t);    Const char* keys[] = {"Display", "Master", "No", "processor"};        for (int i = 0; i < 4; ++i) {Const char* value = Findvaluebykey (&t, keys[i]);        if (value = NULL) {printf ("Find%s\t=\t%s\n", keys[i], value);        } else {printf ("Not Found%s\n", keys[i]);    }} freehashtable (&t);    GetChar (); return 0;}

Simple hash table for C language

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.