哈希表——分离链接法

哈希表又称散列表,是根据关键值而直接进行访问的数据结构。哈希表的实现主要是散列函数和解决冲突。散列函数有:直接寻址法、数字分析法、平法取中法、折叠发、随机数法、除留余数法(严蔚敏版数据结构)。处理冲突的方法有:分离链接法(separate chaining)又称链地址法、开放寻址法、再散列法、建立公共溢出区。本文主要将的是分离链接法的实现。散列函数用的是除留余数法。

编码及测试环境:Visual Studio 2010

fatal.h处理错误的宏定义

#include <stdio.h>
#include <stdlib.h>

#define FatalError(str) fprintf(stderr, "%s\n", str),exit(1)
hashsep.h操作函数的声明
typedef int ElementType;
typedef unsigned int Index;

#ifndef HASHSEQ_H
#define HASHSEQ_H

struct Node
{
	ElementType Element;
	struct Node *Next;
};
typedef struct Node *Position;

struct HashTbl
{
	int TableSize;//表的大小
	Position *TheLists;//存放指针的数组,二级指针
};
typedef struct HashTbl *HashTable;

HashTable InitializeTable();//创建hash表
void Insert(ElementType Key, HashTable H);//插入关键字
Position Find(ElementType Key, HashTable H);//查找
void DestoryTable(HashTable H);//销毁hash表

#endif
hashsep.c操作函数的实现
#include "fatal.h"
#include "hashseq.h"
#include <stdlib.h>

//hash表的最小值
#define HashTableSize (11)

HashTable InitializeTable()
{
	HashTable H;
	int i;

	H = (HashTable)malloc(sizeof(struct HashTbl));
	if(H == NULL)
		FatalError("Out of space");
	else
	{
		H->TableSize = HashTableSize;
		H->TheLists = (Position *)malloc(sizeof(Position) * H->TableSize);
		//没有头结点的链表,将指针初始化为NULL
		for(i = 0 ; i < H->TableSize; i++)
			H->TheLists[i] = NULL;
	}

	return H;
}

static Index Hash(ElementType Key, int Size)
{
	return Key % Size;
}

void Insert(ElementType Key, HashTable H)
{
	Position P, TmpCell;
	Index Val;

	Val = Hash(Key, H->TableSize);
	P = H->TheLists[Val];
	while(P && P->Element != Key)
		P = P->Next;
	
	//如果表中不存在则采用头插法插入新的Key
	if(P == NULL)
	{
		TmpCell = (Position)malloc(sizeof(struct Node));
		TmpCell->Element = Key;
		TmpCell->Next = H->TheLists[Val];
		H->TheLists[Val] = TmpCell;
	}
}

Position Find(ElementType Key, HashTable H)
{
	Position P;

	P = H->TheLists[Hash(Key, H->TableSize)];
	while(P && P->Element != Key)
		P = P->Next;
	return P;
}

void DestoryTable(HashTable H)
{
	int i;
	Position P, Tmp;
	
	for(i = 0; i < H->TableSize; i++)
	{
		P = H->TheLists[i];
		while(P)
		{
			Tmp = P->Next;
			free(P);
			P = Tmp;
		}
	}
	free(H->TheLists);
	free(H);
}
testhash.c测试hash表的实现
#include <stdio.h>
#include <stdlib.h>
#include "hashseq.h"

#define NumItems 400

int main(void)
{
	HashTable H;
	Position P;
	int i, j = 0;
	
	H = InitializeTable();
	for(i = 0; i < NumItems; i++, j += 71)
		Insert(j, H);
	for(i = 0, j = 0; i < NumItems; i++, j += 71)
		if((P = Find(j, H)) == NULL || P->Element != j)
			printf("Error at %d\n", j);
	DestoryTable(H);
	printf("End of program.\n");
	system("Pause");
	return 0;
}

你可能感兴趣的:(散列表,哈希表,分离链接法,链地址法)