散列是一种用于以常数平均时间执行插入、删除和查找的技术。
对于分离链接法,装填因子应接近于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;
}