c语言《数据结构》散列表(哈希表)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

以下是我打的一个散列表,里面的内容主题已经打出来了,可以自行增添;


提示:以下是本篇文章正文内容,下面案例可供参考

#散列表的概念;
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

二、使用步骤

1.定义散列表的结构

代码如下(示例):
结构体定义散列表:
typedef struct node
{
elemstyle data;
struct node* next;
}Node;
typedef struct hnode
{
Node* pn;
int n;
}HNode;



## 1.散列表初始化
代码如下(示例):

HNode* Init_HashTable(int n)
{
	Node* pn = (HNode*)malloc(sizeof(HNode)*n);
	for (int i = 0; i < n; i++)
	{
		pn[i].data = 0;
		pn[i].next = NULL;
	}
	HNode* pt = (HNode*)malloc(sizeof(HNode));
	pt->n = n;
	pt->pn = pn;
	return pt;
}
2.散列表关键码的插入
int insertHashTable(HNode* pt, elemstyle x)
{
	int d = x % pt->n;
	if (pt->pn[d].data == 0)
	{
		pt->pn[d].data = x;
		return true;
	}
		Node* prove = &(pt->pn[d]);
		Node* curr = pt->pn[d].next;
		while (curr&&curr->data!=x)//如果要相同的数据都要存放进去,则去掉curr->data!=x这个判断条件;
		{
			prove = curr;
			curr = curr->next;
		}
		if (curr)
		{
			return false;
		}
			Node* pmove = (Node*)malloc(sizeof(Node));
			pmove->data = x;
			pmove->next = NULL;
			prove->next = pmove;
			return true;
}
3.散列表的释放
int freeHashTable(HNode* pt)
{
	if (pt == NULL)
	{
		return true;
	}
	else
	{
		for (int i = 0; i < pt->n; i++)
		{
			Node* curr = pt->pn[i].next;
			while (curr)
			{
				Node* next = curr->next;
				free(curr);
				curr = next;
			}
		}
		free(pt->pn);
		free(pt);
		return true;
	}
}
4.利用同种方法还可以进行删除关键码,打印等,下面我把全代码写在下面:


**源代码:**
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define true 2
#define false -2
#define maxsize 100
typedef int elemstyle;
//哈希表的定义;
typedef struct node
{
	elemstyle data;
	struct node* next;
}Node;
typedef struct hnode
{
	Node* pn;
	int n;
}HNode;
//哈希表的初始化;
HNode* Init_HashTable(int n)
{
	Node* pn = (HNode*)malloc(sizeof(HNode)*n);
	for (int i = 0; i < n; i++)
	{
		pn[i].data = 0;
		pn[i].next = NULL;
	}
	HNode* pt = (HNode*)malloc(sizeof(HNode));
	pt->n = n;
	pt->pn = pn;
	return pt;
}
//哈希表的释放;
int freeHashTable(HNode* pt)
{
	if (pt == NULL)
	{
		return true;
	}
	else
	{
		for (int i = 0; i < pt->n; i++)
		{
			Node* curr = pt->pn[i].next;
			while (curr)
			{
				Node* next = curr->next;
				free(curr);
				curr = next;
			}
		}
		free(pt->pn);
		free(pt);
		return true;
	}
}
//哈希表的插入;
int insertHashTable(HNode* pt, elemstyle x)
{
	int d = x % pt->n;
	if (pt->pn[d].data == 0)
	{
		pt->pn[d].data = x;
		return true;
	}
		Node* prove = &(pt->pn[d]);
		Node* curr = pt->pn[d].next;
		while (curr&&curr->data!=x)//如果要相同的数据都要存放进去,则去掉curr->data!=x这个判断条件;
		{
			prove = curr;
			curr = curr->next;
		}
		if (curr)
		{
			return false;
		}
			Node* pmove = (Node*)malloc(sizeof(Node));
			pmove->data = x;
			pmove->next = NULL;
			prove->next = pmove;
			return true;
}
//哈希表查找函数;
int findHashTable(HNode* pt, elemstyle val)
{
	int d = val % pt->n;
	if (pt->pn[d].data == 0)
	{
		return false;
	}
	if (pt->pn[d].data == val)
	{
		return true;
	}
	else
	{
		Node* prove = &(pt->pn[d]);
		Node* curr = pt->pn[d].next;
		while (curr && curr->data != val)
		{
			prove = curr;
			curr = curr->next;
		}
		if (curr)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
}
//哈希表的删除;
int deleteHashTable(HNode* pt, elemstyle val)
{
	
	int d = val % pt->n;
	if (pt->pn[d].data == 0)
	{
		return true;
	}
	else if (pt->pn[d].data == val)
	{
		if (pt->pn[d].next == NULL)
		{
			pt->pn[d].data = 0;
			return true;
		}
		else
		{
			Node* curr = pt->pn[d].next;
			pt->pn[d].data = curr->data;
			pt->pn[d].next = curr->next;
			free(curr);
			return true;
		}
	}
	else
	{
		Node* prove = &(pt->pn[d]);
		Node* curr = pt->pn[d].next;
		while (curr && curr->data != val)
		{
			prove = curr;
			curr = curr->next;
		}
		if (curr == NULL)
		{
			return false;
		}
		else
		{
			prove->next = curr->next;
			free(curr);
			return true;
		}
	}
}
//哈希表的打印;
void printHashTable(HNode* pt)
{
	if (pt == NULL)
	{
		printf("打印失败;");
	}
	else
	{
		for (int i = 0; i < pt->n; i++)
		{
			printf("%5d->:",i);
			if (pt->pn[i].data != 0)
			{
				printf("%5d", pt->pn[i].data);
			}
				Node* curr = pt->pn[i].next;
				while (curr)
				{
					printf("->%5d", curr->data);
					curr = curr->next;
				}
				putchar('\n');
		}
	}
}
//主函数;
int main(void)
{
	int n;
	int data;
	printf("输入哈希表的长度:\n");
	scanf("%d", &n);
	//散列表的初始化(哈希表的初始化);
	HNode*pt=Init_HashTable(n);
	//进行数据的插入;
	int val[maxsize];
	printf("输入你关键码;\n");
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &val[i]);
		insertHashTable(pt, val[i]);
	}
	//对要查询的数据进行查询;
	scanf("%d", &data);
	int k=findHashTable(pt, data);
	if (k > 0)
	{
		printf("查找成功;\n");
	}
	else
	{
		printf("查找失败;\n");
	}
	//打印哈希表;
	printHashTable(pt);
	//释放哈希表;
	freeHashTable(pt);
}
# 总结
散列表就是一种查询数据的方式,有很多的方式,比如线性探测法,平方探测法等一系列。
  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心随而动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值