哈希逻辑结构图:
代码实现:
声明:
#define SIZE 13
typedef int KeyData;
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node *next;
}Linklist;
typedef struct Hash
{
Linklist *keytable[SIZE]; //结点类型的指针数组
KeyData nodecount[SIZE]; //存储结点个数
}Hash;
void InitHash(Hash *table);
static KeyData GetKey(DataType data);
int InsertHash(Hash *table, DataType data);
Linklist *SearchHash(Hash *table, DataType value);
int DeleteHash(Hash *table, DataType value);
void ShowHash(Hash *table);
void DestroyHash(Hash *table);
void Test();
方法实现:
#include <stdio.h>
#include "hash.h"
#include <stdlib.h>
#include <math.h>
#include <malloc.h>
#include <assert.h>
//初始化哈希表
void InitHash(Hash *table)
{
if(table == NULL) exit(0);
for(int i = 0; i < SIZE; i++)
{
table->keytable[i] = NULL; //关键值结点的指针指空
table->nodecount[i] = 0; //初始化关键值为0
}
}
//处理关键字方法:这里使用源数据取余
static KeyData GetKey(DataType data)
{
return abs(data % SIZE);
}
//插入
int InsertHash(Hash *table, DataType data)
{
if(table == NULL) exit(0);
KeyData key = GetKey(data);
//判断此次插入的数据是否有重复
Linklist *p = table->keytable[key];
while(p != NULL)
{
if(p->data == data) return 0;
p = p->next;
}
Linklist *node = (Linklist *)malloc(sizeof(Linklist));
assert(node != NULL);
node->data = data;
//第一次插入时,因为初始化NULL,所以让node->next指向NULL
node->next = table->keytable[key];
table->keytable[key] = node;
table->nodecount[key]++;
return 1;
}
//查找值
Linklist *SearchHash(Hash *table, DataType value)
{
if(table == NULL) exit(0);
//先对value做处理
KeyData value_key = GetKey(value);
Linklist *p = table->keytable[value_key];
while(p != NULL)
{
if(value == p->data)
{
return p;
}
p = p->next;
}
return NULL;
}
//删除
int DeleteHash(Hash *table, DataType value)
{
if(table == NULL) exit(0);
KeyData value_key = GetKey(value);
Linklist *p = table->keytable[value_key];
Linklist *q = NULL; //q是p的前驱结点
while(p != NULL)
{
if(p->data == value)
{
//删除的是首结点
if(q == NULL)
{
table->keytable[value_key] = p->next;
}
//删除的是非首结点
else
{
q->next = p->next;
}
free(p);
p = NULL;
return 1;
}
else
{
q = p;
p = p->next;
}
}
return 0;
}
//输出哈希表
void ShowHash(Hash *table)
{
if(table == NULL) exit(0);
for(int i = 0; i < SIZE; i++)
{
printf("余数是%d的数据项",i);
Linklist *p = table->keytable[i];
while(p != NULL)
{
printf("%d ",(int)p->data);
p = p->next;
}
printf("\n");
}
}
//销毁哈希表
void DestroyHash(Hash *table)
{
if(table == NULL) exit(0);
for(int i = 0; i < SIZE; i++)
{
Linklist *p = table->keytable[i];
while(p != NULL)
{
table->keytable[i] = p->next;
free(p);
p = table->keytable[i];
}
table->nodecount[i] = 0;
}
}
void Test()
{
Hash test;
//插入值
InitHash(&test);
for(int i = 0; i < 30; i++)
{
InsertHash(&test, i);
}
ShowHash(&test);
//查找值
Linklist *m = SearchHash(&test, 27);
if(m != NULL)
{
printf("找到了,地址是%p\n", m);
}
else
{
printf("没找到\n");
}
//删除值
printf("\n\n");
if(DeleteHash(&test, 16))
{
printf("删除成功!\n");
}
else
{
printf("删除失败!\n");
}
ShowHash(&test);
//销毁表
DestroyHash(&test);
}
主函数:
#include <stdio.h>
#include "hash.h"
int main()
{
Test();
return 0;
}