哈希表实现

学习于:https://www.bilibili.com/video/BV1sL4y1e7hU?p=2&share_source=copy_pc

#include<assert.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

//用于存放哈希表中各个元素的节点
//其中key是节点的键,data指向的是节点所持有的数据
//next指向该节点的下一个节点
typedef struct listnode
{
	struct listnode* next;
	int key;
	void* data;
}listnode_t;

//用于存放哈希表各个哈希桶首元素的链表,list是一个指针类型
typedef listnode_t* list;
//用于存放各个哈希桶元素
typedef listnode_t* element;

//哈希表,包括该哈希表哈希桶的数目以及哈希桶链表的首节点
typedef struct hashtable {
	unsigned int tablesize;
	list* thelists;	 //注意这里是一个二维链表,listnode_t ** 第一维指向的是哈希桶链表,该链表无有效数据,只是为了索引和哈希分类,第二维指向的是哈希桶中所包含元素的链表
}hashtable_t;

//哈希函数,通过键值找到对应哈希桶的下标,也就是找到所属的哈希桶
int hashfunc(int key, int tablesize)
{
	assert(key >= 0);
	return (key % tablesize);
}

//哈希表初始化
hashtable_t* inithash(int size)
{
	int i = 0;
	hashtable_t* htable = NULL;

	assert(size);

	htable = (hashtable_t*)malloc(sizeof(hashtable_t));
	if (NULL == htable)
	{
		printf("malloc fail \n");
		return NULL;
	}
	htable->tablesize = size;
	htable->thelists = (list*)malloc(sizeof(list) * size);
	if (NULL == htable->tablesize)
	{
		printf("malloc fail2");
		free(htable);
		return NULL;
	}
	for (i = 0; i < size; i++)
	{
		htable->thelists[i] = (listnode_t*)malloc(sizeof(listnode_t));
		if(NULL == htable->thelists){
			free(htable->thelists);
			free(htable);
			return NULL;
		}
		else {
			memset(htable->thelists[i],0,sizeof(listnode_t));
		}
	}
	return htable;
}

//通过键值寻找其在哈希桶中的元素
element hash_find(hashtable_t* hashtable, int key)
{
	int i = 0;
	list L = NULL;
	element e = NULL;
	i = hashfunc(key, hashtable->tablesize);
	L = hashtable->thelists[i];
	e = L->next;
	while (e != NULL && e->key != key)
	{
		e = e->next;
	}
	return e;
}

//通过键和值将该元素插入哈希表中
void hash_insert(hashtable_t* hashtable, int key, void* value)
{
	element e = NULL, temp = NULL;
	list L = NULL;
	e = hash_find(hashtable, key);

	if (NULL == e)
	{
		temp = (element)malloc(sizeof(listnode_t));
		if (NULL == temp)
		{
			printf("malloc fail 3\n");
			return;
		}
		L = hashtable->thelists[hashfunc(key, hashtable->tablesize)];
		temp->data = value;
		temp->key = key;
		temp->next = L->next;
		L->next = temp;
	}
	else {
		printf("key already exist\n");
	}
}

//删除某一键值对应的元素
void hash_delete(hashtable* hashtable, int key)
{
	element e = NULL, last = NULL;
	list L = NULL;
	int i = hashfunc(key,hashtable->tablesize);
	L = hashtable->thelists[i];

	last = L;
	e = L->next;
	while (e!= NULL && e->key!=key)
	{
		last = e;
		e = e->next;
	}
	if (e)
	{
		last->next = e->next;
		free(e);
	}
}

//销毁整个哈希表,释放申请的内存
void hash_destory(hashtable_t* hashtable)
{
	int i = 0;
	list L = NULL;
	element cur = NULL, next = NULL;
	for (i = 0; i < hashtable->tablesize; i++)
	{
		L = hashtable->thelists[i];
		cur = L->next;
		while (cur != NULL)
		{
			next = cur->next;
			free(cur);
			cur = next;
		}
		free(L);
	}
	free(hashtable->thelists);
	free(hashtable);
}

//获取哈希表中某元素对应的data
void* hash_get(element e)
{
	return e ? e->data : NULL;
}

//定义了一个哈希元素所保存的data
typedef struct student{
	int index;
	const char* name;
	int age;
	bool isman;
}student_t;

//主函数实现
int main(void)
{
	student_t p1 = {1, "bryan",19,true };
	student_t p2 = {2, "jason",20,true };
	student_t p3 = {3, "rose",19,true };

	student_t* elems[] = {&p1,&p2,&p3};
	hashtable_t* whash=NULL;
	whash = inithash(31);
	hash_insert(whash, elems[0]->index, elems[0]);
	hash_insert(whash, elems[1]->index, elems[1]);
	hash_insert(whash, elems[2]->index, elems[2]);
	hash_delete(whash,1);

	for (int i = 0; i < 4; i++)
	{
		element e = hash_find(whash,i);
		if (e)
		{
			student_t* get = (student_t*)hash_get(e);
			printf("find name:%s, age:%d, isman?:%d \n",get->name,get->age,get->isman);
		}
		else {
			printf("not find\n");
		}
	}

	system("pause");

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值