您的位置:首页 > 其它

描述一个避免初始化散列表的过程(以消耗内存为代价)

2016-05-14 18:02 656 查看
数据结构与算法分析——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--];
}


main.cpp

#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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: