散列表实现(分离链接法)

散列是一种用于以常数平均时间执行插入、删除和查找的技术。

对于分离链接法,装填因子应接近于1。

main函数还不知道怎么打印。。。 快期中考试了你懂的。

// HashTable.cpp : 定义控制台应用程序的入口点。
//解决冲突的第一种方法叫做分离链接法,其做法是将散列到
//同一值得所有元素保留到一个表中。

#include "stdafx.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>

#define MinTableSize 5
//#define StrLength  4
typedef char* ElementType;
typedef unsigned int Index;
struct ListNode;
typedef struct ListNode* Position;
struct  HashTbl;
typedef struct HashTbl* HashTable;
void error(char* str)
{
	printf("%s\n", str);
	exit(1);
}
struct ListNode
{
	ElementType Element;
	Position Next;
};
typedef Position List;
struct  HashTbl
{
	int TableSize;
	List* TheLists;
};
HashTable InitTable(int TableSize);
Index Hash(const char* Key, int TableSize);
Position Find(ElementType Key, HashTable H);
bool Insert(ElementType key, HashTable H);
bool Delete(ElementType key,HashTable H);
Position FindPrevious(ElementType key, List L);

static int NextPrime(int TableSize);
static bool IsPrime(int num);
static int Fmod(int a, int b, int c);

Index Hash(const char* Key, int TableSize)
{
	unsigned int HashVal = 0;
	while (*Key != '\0')
	{
		HashVal += *Key++;
	}
	return HashVal%TableSize;
}
HashTable InitTable(int TableSize)
{
	HashTable H;
	int i = 0;
	if (TableSize < MinTableSize)
	{
		error("TableSize is too small");
	}
	//散列表结构分配空间
	H = (HashTable)malloc(sizeof(struct HashTbl));
	if (H == NULL)
		error("Out Of Memory");
	H->TableSize = NextPrime(TableSize);
	//初始化List指针的数组
	H->TheLists = (List*)malloc(sizeof(List)*H->TableSize);
	if (H->TheLists == NULL)
		error("Out Of Memory");
	for (i = 0; i < H->TableSize; i++)
	{
		//表头
		H->TheLists[i] = (ListNode*)malloc(sizeof(struct ListNode));
		if (H->TheLists[i] == NULL)
			error("Out Of Memory");
		else
			H->TheLists[i]->Next = NULL;
	}
	return H;
}
Position Find(ElementType Key, HashTable H)
{
	Position P;
	List L;
	L = H->TheLists[Hash(Key, H->TableSize)];
	P = L->Next;
	while (P != NULL&&Key != P->Element)
	{
		P = P->Next;
	}
	return P;
}
bool Insert(ElementType key, HashTable H)
{
	Position Pos, NewCell;
	List L;
	Pos = Find(key, H);
	// key不在散列表中
	if (Pos == NULL)
	{
		NewCell = (Position)malloc(sizeof(struct ListNode));
		if (NewCell == NULL)
			error("Out Of Memory");
		else
		{
			int k = Hash(key, H->TableSize);
			L = H->TheLists[Hash(key, H->TableSize)];
			NewCell->Next = L->Next;
		//	strcpy_s(NewCell->Element, StrLength, key);
			NewCell->Element = key;
			L->Next = NewCell;
		}
		return true;
	}
	return false;
}
bool Delete(ElementType key, HashTable H)
{
	Position P, Pre;
	List L;
	L = H->TheLists[Hash(key, H->TableSize)];
	Pre = FindPrevious(key, L);
	if (Pre == NULL)
		return false;
	P = Pre->Next;
	Pre->Next = P->Next;
	free(P);
	return true;
}
Position FindPrevious(ElementType key, List L)
{
	Position P;
	P = L;
	while (P->Next != NULL&&P->Next->Element != key)
		P = P->Next;
	return P;
}
static int Fmod(int a, int b, int c)//快速模取幂  
{
	if (b == 1) return a;
	int t = Fmod(a, b / 2, c);
	t = (t * t) % c;
	if (b & 1) t = (t * a) % c;
	return t;
}
static bool IsPrime(int num)//米勒-拉宾算法  
{
	for (int i = 0; i < 100; ++i)
	{
		if (Fmod(rand() % (num - 1) + 1, num - 1, num) != 1)
			//a的取值为[1,num-1],a的值需要变化,所以用到随机函数  
			return false;
	}
	return true;
}
static int NextPrime(int TableSize)
{
	while (!IsPrime(TableSize))
	{
		TableSize++;
	}
	return TableSize;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值