C语言实现HashMap
Myhash.h中定义哈希节点,采用邻接表避免哈希冲突。
/*
*file:Myhash.h
*定义节点以及相关操作哈希表函数
*
*/
#ifndef _Myhash_
#define _Myhash_
#include<stdio.h>
typedef void* typeKey;
typedef void* typeValue;
typedef struct Hashnode {
typeKey key;
typeValue value;
struct Hashnode *next;
}Hashnode;
typedef struct HashMap {
Hashnode *map;
size_t ArraySize;
int NowSize;
}HashMap;
unsigned int FNVHash(char *str, unsigned int len);
HashMap *CreateMap(int size);
int Hashinsert(HashMap *hashmap, char *str,char *value);
char *SerchValue(HashMap *hashmap, char *key);
void DestoryMap(HashMap *hashmap);
#endif
实现哈希函数以及相关插入,查询操作
/*
*file:Myhash.c
*实现哈希函数以及相关插入,查询操作
*
*
*/
#include "Myhash.h"
#include <stdlib.h>
#include <string.h>
unsigned int FNVHash(char* str, unsigned int len)
{
const unsigned int fnv_prime = 0x811C9DC5;
unsigned int hash = 0;
unsigned int i = 0;
for(i = 0; i < len; str++, i++)
{
hash *= fnv_prime;
hash ^= (*str);
}
return hash;
}
HashMap *CreateMap(int size) {
HashMap *hashmap = (HashMap *)malloc(sizeof(HashMap));
hashmap->ArraySize = size;
hashmap->NowSize = 0;
hashmap->map = (Hashnode *)malloc(size * sizeof(Hashnode));
for (int i = 0; i < hashmap->ArraySize;i++) {
hashmap->map[i].key = NULL;
hashmap->map[i].value = NULL;
hashmap->map[i].next = NULL;
}
return hashmap;
}
int Hashinsert(HashMap *hashmap, char *str,char *value) {
unsigned int key = FNVHash(str,strlen(str));
key = key % (hashmap->ArraySize);
printf("%d\n", key);
if(hashmap->map[key].value != NULL) {
Hashnode *temp = hashmap->map[key].next;
while(temp != NULL) {
temp = temp->next;
}
Hashnode *node = (Hashnode *)malloc(sizeof(Hashnode));
node->key = (char *)malloc((strlen(str)+1)* sizeof(char));
node->value = (char *)malloc((strlen(value) + 1) * sizeof(char));
strcpy((char*)node->key,str);
strcpy((char*)node->value,value);
hashmap->map[key].next = node;
hashmap->NowSize++;
return 0;
}
hashmap->map[key].key = (char *)malloc((strlen(str)+1) * sizeof(char));
hashmap->map[key].value = (char *)malloc((strlen(value)+1) * sizeof(char));
strcpy((char *)hashmap->map[key].key, str);
strcpy((char *)hashmap->map[key].value, value);
hashmap->NowSize++;
return 0;
}
char* SerchValue(HashMap *hashmap, char *key) {
unsigned int hashcode = FNVHash(key,strlen(key));
int index = hashcode % (hashmap->ArraySize);
Hashnode *temp = &(hashmap->map[index]);
while(strcmp(temp->key,key) != 0 ) {
temp = temp->next;
}
return temp->value;
}
void DestoryMap(HashMap *hashmap) {
if(hashmap == NULL) {
printf("this is empty map\n");
}
for (int i = 0; i < hashmap->ArraySize;i++) {
Hashnode *temp = hashmap->map[i].next;
while(temp != NULL) {
Hashnode *p = temp;
temp = temp->next;
free(p->key);
free(p->value);
free(p);
}
if(&(hashmap->map[i]) != NULL && hashmap->map[i].key != NULL && hashmap->map[i].value != NULL ) {
free(hashmap->map[i].key);
free(hashmap->map[i].value);
}
}
free(hashmap);
}
void PrintfMap(HashMap *hashmap) {
for (int i = 0; i < hashmap->ArraySize;i++) {
Hashnode *node = hashmap->map[i].next;
if(&(hashmap->map[i]) != NULL && hashmap->map[i].key != NULL && hashmap->map[i].value != NULL ) {
if(hashmap->map[i].next != NULL)
{
printf("%s -> %s ", (char *)(hashmap->map[i].key), (char *)(hashmap->map[i].value));
fflush(stdout);
}
else {
printf("%s -> %s \n", (char *)(hashmap->map[i].key), (char *)(hashmap->map[i].value));
}
}
while(node != NULL) {
printf("%s -> %s ", (char *)(node->key), (char *)(node->value));
fflush(stdout);
node = node->next;
if(node == NULL) {
printf("\n");
break;
}
}
}
}
int main() {
HashMap *map = CreateMap(10);
Hashinsert(map,"hello","world");
Hashinsert(map,"hello1","world1");
Hashinsert(map,"hello2","world2");
Hashinsert(map,"hello3","world3");
Hashinsert(map,"hello4","world4");
Hashinsert(map,"hello5","world5");
Hashinsert(map,"hello6","world6");
Hashinsert(map,"hello7","world7");
printf("map size is %d\n", map->NowSize);
char res[100];
char *ptr = SerchValue(map, "hello4");
strcpy(res, ptr);
printf("%s\n", res);
PrintfMap(map);
DestoryMap(map);
}
测试结果
2
7
4
5
2
3
0
1
map size is 8
world4
hello6 -> world6
hello7 -> world7
hello -> world hello4 -> world4
hello5 -> world5
hello2 -> world2
hello3 -> world3
hello1 -> world1