C Language < Division hashing > Efficient HashTable Dictionary, regardless of the collection size, arbitrary length according to key query is only one address around, so the fastest time complexity of o1!
First on the code, write the principle note tomorrow!
HashDictionary.h
#define Cm_str_hashfunc_constant 31#define KEYSIZE 40struct entry{int hashcode;int next;char key[keysize];void* value;}; struct hashdictionary{int* buckets; entry* entrys;int bucketslength;int entryslength;int count;int freelist;int freecount;}; static int primes[] = {3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 91 9,1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591,17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437,187751, 225307, 270371, 324449, 389357, 467237, 560689, 6 72827, 807403, 968897, 1162687, 1395263,1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369};/ /Get Hashint GetHashCode (char* str);//whether Prime number bool IsPrime (int candidate);//Get >min nearest prime number int getprime (int min);//Initialize void Initialize (hashdictionary* HD);//Initialize void Initialize (hashdictionary* hd,int capacity);//release void Disponse ( hashdictionary* HD);//redefine size void Resize (hashdictionary* HD);//Insert Add if True and key exists, then return-1, otherwise replace the new value int Insert (hashdictionary* hd,char* key,void* value,bool Add);//find subscript not returned -1int Findentryindex (hashdictionary* hd,char* key);//lookup does not return nullentry* findentry (hashdictionary* hd,char* key);//delete If you do not return Falsebool Remove (hashdictionary* hd,char* key);//Whether it contains Keybool ContainsKey (hashdictionary* hd,char* key); int GetCount (hashdictionary* HD); void Getallkey (hashdictionary* hd,char* allkey);
HashDictionary.cpp
#include "stdafx.h" #include "HashDictionary.h" #include <malloc.h> #include <math.h> #include <limits.h > #include <string.h>int GetHashCode (char* str) {int Hashcode=0;char *p;for (p=str; *p; p++) {hashcode = hashcode* Cm_str_hashfunc_constant + *p;} return hashcode;} BOOL IsPrime (int candidate) {if ((candidate & 1) = 0) {int limit = (int) sqrt ((double) candidate); int Divisor;for (Divis or = 3; Divisor <= limit; Divisor + = 2) {if ((candidate% divisor) = = 0) return false;} return true;} Return (candidate = = 2); }int getprime (int min) {if (min < 0) return 3;int i;int length=sizeof (primes)/sizeof (primes[0]); for (i = 0; i < lengt H i++) {int prime = primes[i];if (prime >= min) return prime;} for (int i = (min | 3); i < int_max;i+=2) {if (IsPrime (i)) return i;} return min;} void Initialize (hashdictionary** HD) {Initialize (*hd,3);} void Initialize (hashdictionary* hd,int capacity) {int size=getprime (capacity); hd->buckets= (int*) malloc (sizeof ( int) *size); int i = 0;for (; I &Lt Size i++) {hd->buckets[i]=-1;} hd->bucketslength=size;hd->entrys= (entry*) malloc (sizeof (Entry) *size); i = 0;for (; i < size; i++) {hd-> entrys[i].hashcode=-1;hd->entrys[i].next=-1;hd->entrys[i].value=0;} hd->entryslength=size;hd->count=0;hd->freecount=0;hd->freelist=-1;}; void Disponse (hashdictionary* HD) {free (hd->buckets), free (Hd->entrys);} void Resize (hashdictionary* HD) {int newsize=hd->count*2;int* newbuckets= (int*) malloc (sizeof (int) *newsize); entry* newentrys= (entry*) malloc (sizeof (Entry) *newsize), int i = 0;for (; i < newsize; i++) {newbuckets[i]=-1;} for (i = 0; i < newsize; i++) {newentrys[i].hashcode=-1;newentrys[i].next=-1;newentrys[i].value=0;} hd->bucketslength=hd->entryslength=newsize;memcpy (newentrys,hd->entrys,sizeof (Entry) *hd->count); Free (hd->buckets), free (Hd->entrys), hd->buckets=newbuckets;hd->entrys=newentrys;//rearrange for (int i = 0; i < hd->count; i++) {if (hd->entrys[i].hashcode >= 0) {int bucket= hd->entrys[i].hashcode% Hd->bucketslength;hd->entrys[i].next = hd->buckets[bucket];hd->buckets[ Bucket] = i;}}} int Insert (hashdictionary* hd,char* key,void* value,bool add) {int hashcode = GetHashCode (key) & 0x7fffffff;int Target Bucket = hashcode% hd->bucketslength;//new valueint i = hd->buckets[targetbucket];for (i = HD->BUCKETS[TARGETBU Cket]; I >= 0; i = hd->entrys[i].next) {if (Hd->entrys[i].hashcode = = Hashcode && strcmp (hd->entrys[i].key,key) ==0) { if (add) {return-1;} Hd->entrys[i].value = Value;return 2;}} int index;if (Hd->freecount > 0) {index = hd->freelist;hd->freelist =hd-> entrys[index].next;hd-> freecount--;} else {if (Hd->count = = hd->entryslength) {Resize (HD); targetbucket = hashcode% Hd->bucketslength;} index = hd->count;hd->count++;} /*if (buckets[targetbucket]!=-1) printf ("Collision"); */hd->entrys[index].hashcode = Hashcode;hd->entrys[index].next = hd->buckets[targetbucket];memcpy (hd-> Entrys[index].key,key,strlen (key) +1); hd->entrys[index].value = Value;hd->buckets[targetbucket] = index; return 1;} int Findentryindex (hashdictionary* hd,char* key) {int hashcode = GetHashCode (key) & 0x7fffffff;int i = hd->buckets[ Hashcode% hd->bucketslength];for (; I >= 0; i = hd->entrys[i].next) {//printf ("%s Find item \ n", entrys[i].key); I F (hd->entrys[i].hashcode = = Hashcode && strcmp (hd->entrys[i].key,key) ==0) {return i;}} return-1;} entry* findentry (hashdictionary* hd,char* key) {int Index=findentryindex (hd,key), if (index>=0) {return &hd-> Entrys[index];} return 0;} BOOL Remove (hashdictionary* hd,char* key) {int hashcode = GetHashCode (key) & 0x7fffffff;int bucket = hashcode% Hd-> Bucketslength;int last = -1;for (int i = hd->buckets[bucket]; i >= 0; last = i, i = Hd->entrys[i].next) {if (hd- >entrys[i].hashcode = = Hashcode && strcmp (hd->entrys[i].key,key) ==0) {if (last < 0) {hd->buckets[ Bucket] = Hd->entrys[i].next;//if the first}else {hd->entrys[last].next = Hd->entrys[i].next;} Hd->entrys[i].hashcode = -1;hd->entrys[i].next = hd->freelist;//serial logical Delete list memset (hd->entrys[i].key,0,20) ; Hd->entrys[i].value =0;hd->freelist = I;hd->freecount++;return true;}} return false;} BOOL ContainsKey (hashdictionary* hd,char* key) {return Findentryindex (Hd,key) >= 0;} int GetCount (hashdictionary* HD) {return hd->count-hd->freecount;} void Getallkey (hashdictionary* hd,char* allkey) {int length= (hd->count-hd->freecount); Memset (allkey,0,keysize *length); int bytelength=keysize*length;for (int i = 0; i < hd->entryslength; i++) {if (hd->entrys[i].hashcode!=- 1) {//strcat_s (Allkey,bytelength,hd->entrys[i].key); memcpy_s (Allkey+i*keysize,bytelength,hd->entrys[i]. key,keysize);}}}
Test code
TestDic.cpp: Defines the entry point of the console application. #include "stdafx.h" #include "HashDictionary.h" #include <malloc.h> #include <Windows.h> #include < Time.h>int _tmain (int argc, _tchar* argv[]) {//dark 89757hashdictionary* hashdic= (hashdictionary*) malloc (sizeof ( hashdictionary) Initialize (hashdic,3);//3 This parameter is the default array initial size, is generally set to = estimate how many data, small also does not matter, is the dynamic growth of #pragma region basic operation Insert ( Hashdic, "abc", "This ABC value", True); Insert (Hashdic, "12341", "This 12341 value~~~~", true); Insert (Hashdic, "name", " People self-improvement! ", true); Insert (Hashdic," 32.252 "," This ABC value ", True);p rintf (" ABC:%s \ n ", Findentry (Hashdic," abc ")->value); Nsert (Hashdic, "abc", "This NEW v~~~~", false);//<-FALSEPRINTF ("ABC:%s \ n", Findentry (Hashdic, "abc")->value); printf ("Name:%s \ n", Findentry (Hashdic, "name")->value); int Count=getcount (hashdic);p rintf ("Number of table bars:%d\n", count); char* allkey= (char*) malloc (count*keysize); Getallkey (Hashdic,allkey);//The result of the return is a character set in KEYSIZE unit length = "keysize+keysize+keysize+keysizefor (int i = 0; i < count; i++ ) {printf ("Key item:%s\n", allkey+i*keysize);//snack output should be i*keysize~ (i+1) *keysize This paragraph is a key} #pragma endregionentry* find;printf (" ---------------------------------------------\ n "); #pragma region delete insertion time detection clock_t start, finish; Double duration; char* value= "This is a common value~~~~"; start = clock (); int i = 0;char tempkey[20];for (; i < 1000000; i++) {_itoa_s (i,tempkey,10), if (i==50000) {Insert (Hashdic,tempkey, "this Debug ", True);} Insert (hashdic,tempkey,value,true);} finish = Clock (); Duration = (double) (finish-start)/clocks_per_sec; printf ("Insert Hashtable 1 million number of articles: 1 million! Consumption time:%f seconds\n ", duration); printf ("Number of table bars:%d\n", GetCount (Hashdic)); Remove (hashdic, "100"); Remove (Hashdic, "235"); Remove (Hashdic, "888888");//detects whether all inserts exist for (i = 0;i < 1000000; i++) {_itoa_s (i,tempkey,10); find= findentry (Hashdic, Tempkey); if (find==null) printf ("%s not found!!! \ n ", Tempkey); else{//printf ("%s\n ", find->value); Printing 1 million is time consuming}}printf (" Check 1 million complete ~\n "), #pragma endregionprintf ("- -------------------------------------------\n "), start = Clock (), char *testkey=" 50000 "; find= findentry (Hashdic,testkey);p rintf (" Specify Key lookup: key:%s value:%s\n ", Testkey,find->value); char *testkey2= "50001"; find= findentry (Hashdic,testkey2);p rintf ("Specify Key lookup: key:%s value:%s\ n ", testkey2,find->value); finish = Clock (); Duration = (double) (finish-start)/clocks_per_sec; printf ("Find two time:%f seconds\n", duration); printf ("---------------------------------------------\ n"); start = Clock (); Insert (Hashdic, "kanji", "This kanji value", true); Find= findentry (hashdic, "kanji");p rintf ("Specify Key lookup: key:%s value:%s\n", "Kanji", find->value);d uration = (double) (Finish- Start)/clocks_per_sec; printf ("Insert + Find time:%f seconds\n", duration); printf ("Table number:%d\n", GetCount (Hashdic)); System ("pause"); return 0;}
Demo Source Download Address 1: Link: http://pan.baidu.com/s/1vstEu Password: Y5LQ
Demo Source Download Address 2:http://bcs.duapp.com/darkweb/testdic.zip
C Language < Division hashing > High Efficiency HashTable Dictionary