数据结构与算法分析——c语言描述 第五章 分离链接散列表
从书上的代码小改一下。插入的时候自动选择是否再散列,所以insert要返回一个hashtable。
还有增加是否查抄成功。(虽然可以通过返回-1来返回查找失败)
hashQuad.h
typedef char* ElementType; #ifndef _HashQuad_H #define _HashQuad_H 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); HashTable insert(ElementType key, HashTable h); HashTable rehash(HashTable h); ElementType retrive(Position p,HashTable h); int isLegitimate(Position pos, HashTable h); #endif
hashQuad.c
#include"hashQuad.h" #include"fatal.h" #include<math.h> #include<string.h> #define MinTableSize 10 enum KindOfEntry { Legitimate, Empty, Deleted }; struct HashEntry { ElementType element; enum KindOfEntry info; }; typedef struct HashEntry Cell; struct HashTbl { int tableSize; int hasInsertedNum; Cell *theCells;//数组 }; static int hash(ElementType key, int tableSize) { unsigned int hashVal = 0; while (*key != '\0') hashVal = (hashVal << 5) + *key++; return hashVal % (tableSize); } static int isPrime(int num) { for (int i = 2; i <= sqrt(num); i++) if (num%i == 0) return 0; return 1; } static int nextPrime(int num) { int i = num; while (!isPrime(i)) i++; return i; } int isLegitimate(Position pos,HashTable h) { return h->theCells[pos].info == Legitimate; } 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 = nextPrime(tableSize); h->theCells = malloc(sizeof(Cell)*h->tableSize); h->hasInsertedNum = 0; if (h->theCells == NULL) FatalError("Out of space!!!"); for (i = 0; i < h->tableSize; i++) { h->theCells[i].info = Empty; } return h; } void destroyTable(HashTable h) { for (int i = 0; i < h->tableSize; i++) if (h->theCells[i].info == Legitimate) free(h->theCells[i].element); free(h->theCells); free(h); } Position find(ElementType key, HashTable h) { Position currentPos = hash(key, h->tableSize); while (h->theCells[currentPos].info != Empty && strcmp(h->theCells[currentPos].element, key) != 0) { currentPos = (currentPos + 1) % h->tableSize; } return currentPos; } HashTable insert(ElementType key, HashTable h) { if ((double)h->hasInsertedNum / h->tableSize > 0.5) h = rehash(h); Position pos = find(key, h); if (h->theCells[pos].info != Legitimate) { h->theCells[pos].element = malloc(sizeof(char)*strlen(key) + 1); strcpy(h->theCells[pos].element, key); h->theCells[pos].info = Legitimate; h->hasInsertedNum++; } return h; } HashTable rehash(HashTable h) { HashTable newH = initializeTable(h->tableSize * 2); for (int i = 0; i < h->tableSize; i++) if (h->theCells[i].info == Legitimate) insert(h->theCells[i].element, newH); destroyTable(h); return newH; } ElementType retrive(Position p, HashTable h) { return h->theCells[p].element; }
main.c
#include"hashQuad.h" #include<stdio.h> int main() { HashTable h = initializeTable(500); h=insert("aaaaaaa", h); Position p = find("aaaaaaa", h); if (isLegitimate(p, h)) printf("%s", retrive(p, h)); p = find("bbbb", h); if (isLegitimate(p, h)) printf("%s", retrive(p, h)); destroyTable(h); }