頭文件
#ifndef __GHASH_H_ #define __GHASH_H_ #define HASHSIZE 512 typedef struct _Item { char * key; char * value; struct Item * next; } Item; void GHashInit(); Item * HashInSert(char * key,char * value); int HashRemove(char * key); Item * HashSearch(char * key); void FreeGHash(); void PrintGHash(); #endif
c文件
#include<stdio.h> #include<stdlib.h> #include<string.h> #include "GHash.h" static struct Item *hashtab[HASHSIZE]; static void freeItem(Item * item); static unsigned int _Hash(char *key); static unsigned int _ELFHash(char *str); void GHashInit() { int i=0; for(i=0; i<HASHSIZE; i++) { hashtab[i]=NULL; } } Item * HashInSert(char * key,char * value) { Item * np; unsigned int hashval; if((np=HashSearch(key))==NULL) { np=(Item *)malloc(sizeof(Item)); if(NULL==np || NULL ==(np->key = strdup(key)) || NULL ==(np->value = strdup(value)) ) { return NULL; } hashval = _Hash(key); np->next = (Item *)hashtab[hashval]; hashtab[hashval] = np; } else { free(np->value); if((np->value=strdup(value))== NULL) { return NULL; } } return np; } int HashRemove(char * key) { } Item * HashSearch(char * key) { Item *np; for(np = (Item *)hashtab[_Hash(key)]; np != NULL; np = np->next) if(strcmp(key,np->key) == 0) return np; return NULL; } void FreeGHash() { int i=0; for(i=0; i<HASHSIZE; i++) { if(hashtab[i]!=NULL) { Item * tmp; Item * deln; for(tmp=hashtab[i]; tmp!=NULL; tmp=hashtab[i]) { hashtab[i]=tmp->next; freeItem(tmp); } } } } void PrintGHash() { printf("Print Hash:\n"); int i=0; for(i=0; i<HASHSIZE; i++) { if(hashtab[i] !=NULL ) { printf("%d---",i); Item * tmp; for(tmp=hashtab[i]; tmp!=NULL; tmp=tmp->next) { printf("%s:%s;",tmp->key,tmp->value); } printf("\n"); } } } static unsigned int _Hash(char *key) { return _ELFHash(key)%HASHSIZE; } // ELF Hash Function static unsigned int _ELFHash(char *str) { unsigned int hash = 0; unsigned int x = 0; while (*str) { hash = (hash << 4) + (*str++);//hash左移4位,當前字符ASCII存入hash if ((x = hash & 0xF0000000L) != 0) {//如果最高的四位不爲0,則說明字符多餘7個,如果不處理,再加第九個字符時,第一個字符會被移出,因此要有如下處理。 //該處理,如果對於字符串(a-z 或者A-Z)就會僅僅影響5-8位,否則會影響5-31位,因爲C語言使用的算數移位 hash ^= (x >> 24); //清空28-31位。 hash &= ~x; } } //返回一個符號位爲0的數,即丟棄最高位,以免函數外產生影響。(我們可以考慮,如果只有字符,符號位不可能爲負) return (hash & 0x7FFFFFFF); } static void freeItem(Item * item) { free(item->key); free(item->value); free(item); }
使用代碼
Item * np; GHashInit(); if((np=HashInSert("123","abc"))==NULL) { printf("Insert %s:%s wrong\n","123","abc"); } PrintGHash(); if((np=HashInSert("456","def"))==NULL) printf("Insert %s:%s wrong\n","456","def"); PrintGHash(); if((np=HashSearch("123")) ==NULL) { printf("not find 123\n"); } printf("find 123:%s\n",np->value); FreeGHash(); PrintGHash();
說明:
HashInSert 當哈希表中存在了對應的Key值時,則使用新插入的Value替換以前的Value,即覆蓋模式類型