上篇是开放地址法和除留余数法
这篇是用链地址法和除留余数法来完成哈希表的相关操作,代码如下:
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
//除留余数法+链地址法
#define m 13
typedef struct DateType
{
int key;//关键字项
//Info Type otherinfo;//其他数据项
}DataType;
typedef struct Node
{
DataType data;//数据域
struct Node* next;//指向下一个节点
}Node;//链式地址法中的链表节点
typedef struct
{
Node* next;//链表的地址
}HashTable[m];//哈希表
//初始化哈希表
void InitHashTable(HashTable ht)
{
assert(ht != NULL);
if (ht == NULL)
{
return;
}
//初始化
for (int i = 0; i < m; i++)
{
ht[i].next = NULL;
}
}
//计算key的哈希值,哈希函数为H(key)=key%m
static int H(int key)
{
return key % m;
}
//在哈希表中查找key,找到返回节点地址,失败返回NULL
Node* Search(const HashTable ht, int key)
{
int hi = H(key);
for (Node* p = ht[hi].next; p != NULL; p = p->next)
{
if (p->data.key == key)
{
return p;
}
}
return NULL;
}
//将key插入到哈希表ht中,成功返回true,失败返回false
bool Insert(HashTable ht,int key)
{
int hi = H(key);
if (Search(ht, key) != NULL)//key已经存在
{
return false;
}
//插入key
//申请一个节点
Node* p = (Node*)malloc(sizeof(Node));
assert(p != NULL);
p->data.key = key;
//头插
p->next = ht[hi].next;
ht[hi].next = p;
return true;
}
void Show(HashTable ht)
{
for (int i = 0; i < m; i++)
{
printf("哈希值为%d的有:", i);
for (Node* p = ht[i].next; p != NULL; p = p->next)
{
printf("%d ", p->data.key);
}
printf("\n");
}
}
int main()
{
HashTable ht;
InitHashTable(ht);//初始化哈希表
int arr[16] = { 3,5,7,1,2,9,28,25,6,11,10,15,17,23,34,19 };
//测试插入后得到的哈希表
for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
{
Insert(ht, arr[i]);
}
Show(ht);//输出哈希表
return 0;
}