#include<stdio.h> #include"fatal.h" typedef char* ElementType; typedef unsigned int Index; typedef Index Position; struct HashTbl; typedef struct HashTbl *HashTable; HashTable InitializeTable(int TableSize); void DestroyTable(HashTable H); Position Find(ElementType key,HashTable H); void Insert(ElementType key,HashTable H); ElementType Retrieve(Position P,HashTable H); HashTable Rehash(HashTable H); enum KindOfEntry {Legitimate,Empty,Deleted}; struct HashEntry { ElementType Element; enum KindOfEntry Info; }; typedef struct HashEntry Cell; struct HashTbl { int TableSize; Cell *TheCells; }; int MinTableSize=23; HashTable InitializeTable(int TableSize) { HashTable H; int i; if(TableSize<MinTableSize) { Error("Table size too small!"); return NULL; } H=malloc(sizeof(struct HashTbl)); if(H==NULL) FatalError("Out of space !!!"); H->TableSize=TableSize; H->TheCells=malloc(sizeof(Cell)*H->TableSize); if(H->TheCells==NULL) FatalError("Out of space !!"); for(i=0;i<H->TableSize;i++) H->TheCells[i].Info=Empty; return H; } int Hash(ElementType key,int TableSize) { unsigned int HashVal=0; while(*key!='\0') { HashVal=(HashVal<<5)+*key++; } HashVal=HashVal%TableSize; return HashVal; } Position Find(ElementType key,HashTable H) { Position CurrentPos; int CollisionNum; CollisionNum=0; CurrentPos=Hash(key,H->TableSize); while(H->TheCells[CurrentPos].Info!=Empty&&H->TheCells[CurrentPos].Element!=key) { CurrentPos+=2*++CollisionNum-1; if(CurrentPos>=H->TableSize) CurrentPos-=H->TableSize; } return CurrentPos; } void Insert(ElementType key,HashTable H) { Position Pos; Pos=Find(key,H); if(H->TheCells[Pos].Info!=Legitimate) { H->TheCells[Pos].Info=Legitimate; H->TheCells[Pos].Element=key; } } ElementType Retrieve(Position P,HashTable H) { if(H->TheCells[P].Info!=Empty) return H->TheCells[P].Element; else return NULL; } HashTable rehash(HashTable H) { int i,OldSize; Cell* OldCells; OldCells=H->TheCells; OldSize=H->TableSize; H=InitializeTable(2*OldSize); for(i=0;i<OldSize;i++) if(OldCells[i].Info==Legitimate) Insert(OldCells[i].Element,H); free(OldCells); return H; }