数据结构与算法分析——c语言描述 练习5.5e 答案
hashQuad.c
#include"hashQuad.h" #include"fatal.h" #include<math.h> #include<string.h> #define MinTableSize 5 enum KindOfEntry { Legitimate, Empty, Deleted }; struct HashEntry { ElementType element; enum KindOfEntry info; }; typedef struct HashEntry Cell; struct HashTbl { int tableSize; int hasInsertedNum; Cell *theCells;//数组 int* randomArr; }; static int RandInt(int i, int j) { int temp; temp = (int)(i + (1.0*rand() / RAND_MAX)*(j - i)); return temp; } static void getRandomInt(int *A, int n) { for (int i = 0; i < n; i++) { A[i] = i + 1; } for (int i = 1; i < n; i++) { //std::swap(A[i], A[RandInt(0, i)]); int randAdrr = RandInt(0, i); int t = A[i]; A[i] = A[randAdrr]; A[randAdrr] = t; } } static int hash(ElementType key, int tableSize) { return key % (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; h->randomArr = malloc(sizeof(int)*h->tableSize); getRandomInt(h->randomArr, h->tableSize); 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) { free(h->randomArr); free(h->theCells); free(h); } Position find(ElementType key, HashTable h) { Position currentPos = hash(key, h->tableSize); int collisionNum = 0; while (h->theCells[currentPos].info != Empty && h->theCells[currentPos].element != key) { currentPos = (currentPos + h->randomArr[collisionNum++]) % 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 = 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; }
#include<stdlib.h> #include"hashQuad.h" #include<stdio.h> #define N 111 int randIntArr[N];//这么大的数组放在全局变量上,如果放在main里就是放在程序的堆上,运行时再分配。放在外面就是编译时就分配在静态数据那。 int main() { for (int i = 0; i < N; i++) randIntArr[i] = rand(); HashTable h = initializeTable(100); for (int i = 0; i < N; i++) h = insert(randIntArr[i], h); destroyTable(h); }