lvxuzhou


私信TA

用户名:lvxuzhou

访问量:106753

签 名:

lvxuzhou

等  级
排  名 47
经  验 12168
参赛次数 0
文章发表 56
年  龄 0
在职情况 学生
学  校 西安
专  业

  自我简介:

欢迎交流
个人QQ:757368775 
【注意】
添加好友时请注明“来自c语言网”

平时工作主要使用java语言,由于Hashmap在java和C++中用的非常多,于是自己拿C语言实现了简单的Hashmap,
并且增加了检测内存泄漏的功能。目前只支持字符串的key、整数的value。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct Node{
	char key[8];
	long long value;
	long long flag;
	struct Node*next;
}Node;				  
long long mycount=0;  //记录分配内存的次数
Node**hashmap;		  //哈希表
int hash_size=10;	  //哈希表容量
//封装calloc函数
void*Mycalloc(size_t _Count,size_t _Size)
{
	mycount++;
	return calloc(_Count,_Size);
}
//封装free函数
void  Myfree(void* Memory)
{
	mycount--;
	free(Memory);
}
//哈希算法
static unsigned long long hash_33(char* key)
{
	unsigned long long hash = 0;
	while (*key) {
		hash = (hash << 5) + hash + *key++;
	}
	return hash;
}
//初始化哈希表
static void init()
{
	hashmap=(Node**)Mycalloc(hash_size,sizeof(Node*));	
}
//添加元素
static void add(char*key,long long value)
{
	long long hash=hash_33(key)%hash_size;
	Node*head=NULL;
	if (hashmap[hash]==NULL)
	{
		hashmap[hash]=(Node*)Mycalloc(1,sizeof(Node));
	}
	head=hashmap[hash];
	if (head->flag==0)
	{
		strcpy(head->key,key);
		head->value=value;
		head->flag++;
	}
	else
	{
		Node*temp=head;
		Node* node=(Node*)Mycalloc(1,sizeof(Node));
		while(temp->next!=NULL){
			temp=temp->next;
		}
		strcpy(node->key,key);
		node->value=value;
		node->next=NULL;
		temp->next=node;
	}
}
//遍历哈希表
static void show(){
	long long i;
	if (hashmap==NULL)
	{
		printf("hashmap为空");
		return;
	}
	for (i=0;i<hash_size;i++)
	{
		Node*temp=hashmap[i];
		if (temp!=NULL)
		{
			while (temp!=NULL)
			{
				printf("%s=%lld",temp->key,temp->value);
				temp=temp->next;
				if (temp!=NULL)
				{
					putchar(',');
				}
			}
			printf("\n");
		}else{
			printf("本行为空\n");
		}
	}
}
//删除元素
static void del(char*key){
	long long hash=hash_33(key)%hash_size;
	Node*head=hashmap[hash];
	Node*temp=head;
	if(head==NULL){
		printf("删除的链表为空\n");
		return ;
	}
	if(0==strcmp(key,temp->key)&&temp->flag==1){
		hashmap[hash]=temp->next;
		Myfree(temp);
		temp=NULL;
		return;
	}
	while (temp->next!=NULL)
	{
		if(0==strcmp(key,temp->next->key))
		{
			Node*temp1=temp->next;
			if (temp1->next==NULL)//说明是最后一个元素
			{
				temp->next=NULL;
				Myfree(temp1);
			}
			else
			{
				temp=temp1->next;
				Myfree(temp1);
				
			}
			temp1=NULL;
			return;
		}
		temp=temp->next;
	}
	printf("没有找到要删除的元素\n");
}
//清空一个子节点
static void delAll(Node*head){
	Node*temp;
	while(head->next!=NULL)
	{
		temp=head->next;
		head->next=temp->next;
		Myfree(temp);
		temp=NULL;
	}
	Myfree(head);
	head=NULL;
}
//清空哈希表
static void empty(){
	long long i;
	for (i=0;i<hash_size;i++)
	{
		if (hashmap[i]!=NULL)
		{
			delAll(hashmap[i]);
		}
	}
	Myfree(hashmap);
	hashmap=NULL;
}
//获取key对应的value
static Node* getValue(char*key)
{
	long long hash=hash_33(key)%hash_size;
	Node*temp=hashmap[hash];
	while(temp!=NULL){
		if (0==strcmp(key,temp->key))
		{
			printf("hash=%lld 找到了%lld\n",hash+1,temp->value);
			return temp;
		}
		temp=temp->next;
	}
	printf("没有找到\n");
	return NULL;
}
//修改key对应的value
void change(char* key,long long value){
	Node*res=getValue(key);
	if (res==NULL)
	{
		return;
	} 
	else
	{
		res->value=value;
	}
}
//检查内存是否泄漏
void memoryleak()
{
	if (mycount>0)
	{
		printf("内存泄漏%lld\n",mycount);
	}else{
		printf("内存没有泄漏\n");
	}
}
//测试代码
long long main()
{
	long long i;
	char key[8]={0};
	char find[8]={0};
	printf("请选择创建hashmap长度,默认值为10\n");
	scanf("%d",&hash_size);
	getchar();//接收回车键
	init();
	while (1)
	{
		long long select=0;
		printf("--------------------\n");
		printf("请选择\n");
		printf("增加1 key value\n");
		printf("删除2 key\n");
		printf("修改3 key value\n");
		printf("清空4\n");
		printf("查看5\n");
		printf("--------------------\n");
		select=getchar();
		getchar();//接收回车键
		switch (select)
		{
		case '1':
			{
				printf("增加1 key value\n");
				scanf("%s %lld",key,&i);
				add(key,i);
				getchar();//接收回车键
				show();
			}
			break;
		case '2':
			{
				scanf("%s",key);
				del(key);
				getchar();//接收回车键
				show();
			}
			break;
		case '3':
			{
				scanf("%s %lld",key,&i);
				change(key,i);
				getchar();//接收回车键
				show();
			}
			break;
		case '4':		
			{
				empty();
				memoryleak();
			}
			break;
		case '5':		
			{
				show();
			}
			break;
		default:
			printf("请输入正确选项\n");
			getchar();
			break;
		}
	}
	return 0;
}

欢迎交流

个人QQ:757368775 

【注意】

添加好友时请注明“来自c语言网”


 

0.0分

0 人评分

新上线《蓝桥杯辅导》课程,近五年的蓝桥杯省赛与国赛真题都有,从读题开始理解题意、梳理思路、实现代码再提交评测全过程,可有效提升获奖比例甚至进国赛!课程介绍、试听请猛击这里

  评论区

  • «
  • »