欢迎交流
个人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 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复