查找算法刷题【哈希表算法】

一、哈希表结构体

二、代码

#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>



typedef struct Node
{
	char* s;
	struct Node* next;
}g_Node;


typedef struct HashTable
{
	struct Node* node;
	int cnt, size;
}g_HashTable;

//函数的声明
bool insert(g_HashTable* h, const char* s);

/* 创建一个链表节点 */
g_Node* getNewNode(const char* s)
{
	g_Node* pNode = (g_Node*)malloc(sizeof(g_Node));
	pNode->next = NULL;
	pNode->s = (char*)malloc(strlen(s) + 1);
	strcpy(pNode->s, s);
	pNode->s[strlen(s)] = '\0';
	return pNode;
}

/* 创建一个哈希表元素 */
g_HashTable* getNewHashTable(int n)
{
	g_HashTable* pHt = (g_HashTable*)malloc(sizeof(g_HashTable));   //创建哈希表管理结构体
	pHt->node = (g_Node*)malloc(sizeof(g_Node) * n);     //创建哈希表数组
	for (int i = 0; i < n; i++) pHt->node[i].next = NULL;
	pHt->cnt = 0;
	pHt->size = n;
	return pHt;
}


/* 回收哈希表链表节点 */
void clearNode(g_Node* p)
{
	if (p == NULL) return;
	if (p->s)  free(p->s);
	free(p);
}

/* 回收整个哈希表元素 */
void clearHashTable(g_HashTable* h)
{
	if (h == NULL) return;
	for (int i = 0; i < h->size; i++)
	{
		g_Node* p = h->node[i].next, * q;
		while (p)
		{
			q = p->next;
			clearNode(p);
			p = q;
		}
	}
	free(h->node);   //因为数组是统一申请的,所以一块释放了就可以了
	free(h);
	return;
}
/*==============================哈希表扩容操作===============================*/

/* 交换哈希表头 */
void swapHashTable(HashTable* h1, HashTable* h2) {
	g_Node* node;
	int data;
	node = h1->node;
	h1->node = h2->node;
	h2->node = node;
	data = h1->cnt;
	h1->cnt = h2->cnt;
	h2->cnt = data;
	data = h1->size;
	h1->size = h2->size;
	h1->size = data;
	return;
}

/* 哈希表的扩容操作:创建新的哈希表,然后进行移植 */
void expand(g_HashTable* h)
{
	if (NULL == h) return;
	printf("expand Hash Table %d -> %d\n", h->size, h->size * 2);
	g_HashTable* h_new = getNewHashTable(h->size * 2);            //使用函数创建新的哈希表
	for (int i = 0; i < h->size; i++)
	{
		g_Node* p = h->node[i].next;
		while (p)
		{
			insert(h_new, p->s);
			p = p->next;
		}
	}
	h = h_new;
	clearHashTable(h_new);
}


/*=============================哈希表的动作================================*/
/* 字符串的哈希算法 */
int hash_func(const char* s)
{
	int seed = 131, h = 0;
	for (int i = 0; s[i]; i++)
	{
		h = h * seed + s[i];
	}
	return h & 0x7fffffff;
}

/* 向哈希表元素插入一个链表节点 */
bool insert(g_HashTable* h, const char* s)
{
	if (h == NULL) return false;
	if (h->cnt >= h->size * 2) {
		expand(h);
	}
	int hcode = hash_func(s);
	int index = hcode % h->size;
	g_Node* node = getNewNode(s);
	node->next = h->node[index].next;   //直接向后插入,说明哈希数组中的链表头节点不存储数据。
	h->node[index].next = node;
	h->cnt++;    //哈希表中总的元素
	return true;
}

/* 从哈希表中找到对应元素 */
bool find(g_HashTable* h, const char* s)
{
	if (NULL == h) return false;
	int hcode = hash_func(s), index = hcode % h->size;
	g_Node* pnode = h->node[index].next;
	while (pnode)
	{
		if (0 == strcmp(pnode->s, s)) return true;
		pnode = pnode->next;
	}
	return false;
}


/* 哈希表的输出 */
void output(g_HashTable* h) {
	printf("\n\nHash Table(%d / %d) : \n", h->cnt, h->size);
	for (int i = 0; i < h->size; i++) {
		printf("%d : ", i);
		g_Node* p = h->node[i].next;
		while (p) {
			printf("%s -> ", p->s);
			p = p->next;
		}
		printf("\n");
	}
	return;
}


int main()
{
	char s[100];
#define MAX_N 2
	g_HashTable* h = getNewHashTable(MAX_N);
	while (~scanf("%s", s)) {
		if (strcmp(s, "end") == 0) break;
		insert(h, s);
	}
	output(h);
	while (~scanf("%s", s)) {
		printf("find(%s) = %d\n", s, find(h, s));
	}
#undef  MAX_N
	return 0;
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值