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

数据结构与算法分析——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);
}


你可能感兴趣的:(描述一个避免初始化散列表的过程(以消耗内存为代价))