八、哈希Hash

哈希逻辑结构图:

在这里插入图片描述

代码实现:

声明:

#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;
}

测试结果

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值