数据结构与算法分析——c语言描述 练习5.10 答案
不知道这道题是现实意义在哪,就是免去了刚开始给所有KindOfEntry赋值为empty。
hashQuad.h
typedef int ElementType_hash; #ifndef _HashQuad_H #define _HashQuad_H typedef unsigned int Index; typedef Index Position_hash; struct HashTbl; typedef struct HashTbl* HashTable; HashTable initializeTable(int tableSize); void destroyTable(HashTable h); Position_hash find(ElementType_hash key, HashTable h); HashTable insert(ElementType_hash key, HashTable h); HashTable rehash(HashTable h); ElementType_hash retrive(Position_hash p, HashTable h); int isLegitimate(Position_hash pos, HashTable h); #endif
hashQuad.cpp
#include"hashQuad.h" #include"fatal.h" #include<math.h> #include"stack.h" #define MinTableSize 5 struct HashEntry { ElementType_hash element; int whereOnStack; }; typedef struct HashEntry Cell; struct HashTbl { int tableSize; int hasInsertedNum; Cell *theCells;//数组 Stack s; }; struct StackRecord { int Capacity; int TopOfStack; ElementType_stack *Array; }; static int hash(ElementType_hash key, int tableSize) { return key % (tableSize); } static Position_hash hash2(ElementType_hash key, int tableSize) { return 7 - (key % 7); } 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_hash pos, HashTable h) { return h->theCells[pos].whereOnStack >= 0 && h->theCells[pos].whereOnStack <= h->s->TopOfStack && h->s->Array[h->theCells[pos].whereOnStack] == pos; } HashTable initializeTable(int tableSize) { HashTable h; if (tableSize < MinTableSize) { Error("Table size too small"); return NULL; } h = (HashTable)malloc(sizeof(struct HashTbl)); if (h == NULL) FatalError("Out of space!!!"); h->tableSize = nextPrime(tableSize); h->theCells = (Cell *)malloc(sizeof(Cell)*h->tableSize); h->hasInsertedNum = 0; h->s = CreatStack(tableSize); if (h->theCells == NULL) FatalError("Out of space!!!"); return h; } void destroyTable(HashTable h) { DisposeStack(h->s); free(h->theCells); free(h); } Position_hash find(ElementType_hash key, HashTable h) { Position_hash currentPos = hash(key, h->tableSize); int i = 0; while (isLegitimate(currentPos, h) && h->theCells[currentPos].element != key) { printf("%d\n", currentPos); currentPos += (++i * hash2(key, h->tableSize)); currentPos = currentPos % h->tableSize; } return currentPos; } HashTable insert(ElementType_hash key, HashTable h) { if ((double)h->hasInsertedNum / h->tableSize > 0.5) h = rehash(h); Position_hash pos = find(key, h); if (!isLegitimate(pos, h)) { h->theCells[pos].element = key; Push(pos, h->s); h->theCells[pos].whereOnStack = h->s->TopOfStack; h->hasInsertedNum++; } return h; } HashTable rehash(HashTable h) { HashTable newH = initializeTable(h->tableSize * 2); for (int i = 0; i < h->tableSize; i++) if (isLegitimate(i, h)) insert(h->theCells[i].element, newH); destroyTable(h); return newH; } ElementType_hash retrive(Position_hash p, HashTable h) { return h->theCells[p].element; }
stack.h
typedef int ElementType_stack; #ifndef _stack_h #define _stack_h struct StackRecord; typedef struct StackRecord *Stack; int IsEmpty(Stack s); int IsFull(Stack s); Stack CreatStack(int MaxElements); void DisposeStack(Stack s); void MakeEmpty(Stack s); void Push(ElementType_stack X, Stack s); ElementType_stack Top(Stack s); void Pop(Stack s); ElementType_stack TopAndPop(Stack s); #endif
stack.cpp
#include"stack.h" #include<stdlib.h> #include"fatal.h" #define EmptyTOS (-1) #define MinStackSize (5) struct StackRecord { int Capacity; int TopOfStack; ElementType_stack *Array; }; int IsEmpty(Stack s) { return s->TopOfStack == EmptyTOS; } int IsFull(Stack s) { return s->TopOfStack - 1 == s->Capacity; } Stack CreatStack(int MaxElements) { Stack s; if (MaxElements < MinStackSize) Error("Stack size is too small"); s = (Stack)malloc(sizeof(struct StackRecord)); if (s == NULL) Error("out of space"); else { s->Array = (ElementType_stack*)malloc(sizeof(ElementType_stack)*MaxElements); if (s->Array == NULL) Error("out of space"); else { s->Capacity = MaxElements; MakeEmpty(s); } } return s; } void DisposeStack(Stack s) { if (s != NULL) { free(s->Array); free(s); } } void MakeEmpty(Stack s) { s->TopOfStack = EmptyTOS; } void Push(ElementType_stack X, Stack s) { if (IsFull(s)) Error("Full stack"); s->Array[++s->TopOfStack] = X; } ElementType_stack Top(Stack s) { if (IsEmpty(s)) Error("Empty stack"); return s->Array[s->TopOfStack]; } void Pop(Stack s) { if (IsEmpty(s)) Error("Empty stack"); s->TopOfStack--; } ElementType_stack TopAndPop(Stack s) { if (IsEmpty(s)) Error("Empty stack"); return s->Array[s->TopOfStack--]; }
#include"hashQuad.h" #include<stdio.h> int main() { HashTable h = initializeTable(50); for (int i = 0; i < 333; i++) { h = insert(i, h); } Position_hash p = find(332, h); if (isLegitimate(p, h)) printf("%d\n", retrive(p, h)); destroyTable(h); }