尝试自己写一个HashMap,统计一个数组中各个元素的个数,数组设置的比较小,后续再优化,冲突的时采用地址链接法。
#include<stdio.h>
typedef struct Node{
int val;
int count;
struct Node *next;
}node;
#define seed 7
node *p[seed] = {NULL};
int add_hash(int key)
{
int idx = key * key % seed;
if(p[idx]->val == key)//直接找到了
{
p[idx]->count++;
return 0;
}
else //hash冲突,地址链接法
{
//这个地方一定要注意,需要修改的next指向的内容,p为指针数组,p[idx]->next是链表指针
//需要修改的是next指向的内容,所以修改next的内容,需要用指针的指针
node** q = &(p[idx]->next);
while(*q != NULL)
{
if((*q)->val == key)
{
(*q)->count++;
return 0;
}
else
*q = (*q)->next;
}
node* newp = (node*)malloc(sizeof(node));
if(newp == NULL)
{
printf("malloc err!\n");
return -1;
}
//在这里修改next的指向
*q = newp;
newp->val = key;
newp->count++;
newp->next = NULL;
return 0;
}
}
int get_hash(int key)
{
int idx = key*key%seed;
if(p[idx]->val == key)
{
return p[idx]->count;
}
else
{
node* q = p[idx]->next;
while(q != NULL)
{
if(q->val == key)
return q->count;
else
q = q->next;
}
}
printf("can't find key:%d in hash\n",key);
return 0;
}
int destroy_hash()
{
int i = 0;
for(;i < seed; i++)
{
node* q = p[i]->next;
while(q != NULL)
{
node* m = q->next;
free(q);
q = m;
}
}
printf("hash has destroyed\n");
return 0;
}
void trverse_hash()
{
int i = 0;
for(;i < seed; i++)
{
printf("key:%d count:%d", p[i]->val, p[i]->count);
node* q = p[i]->next;
while(q != NULL)
{
printf("-->key:%d count:%d", q->val, q->count);
q = q->next;
}
printf("\n");
}
return;
}
int init_hash()
{
int i = 0;
for(; i < seed; i++)
{
p[i] = (node*)malloc(sizeof(node));
if(p[i] == NULL)
{
printf("malloc err! init hash failed!\n");
return -1;
}
p[i]->val = i;
p[i]->count = 0;
p[i]->next = NULL;
}
return 0;
}
int main()
{
int ret = init_hash();
if(ret != 0)
return -1;
int num[5] = {1,2,2,1,3};
int i = 0;
for(; i < 5; i++)
add_hash(num[i]);
//add_hash(2);
//int key = 2;
//printf("%d出现的次数:%d\n", key, get_hash(key));
trverse_hash();
destroy_hash();
return 0;
}