由于C++中没有现成的哈希表可以实现,必须自己实现,在此记录一下哈希表的实现过程,希望对你有帮助
头文件:
chtbl.h
#pragma once
#ifndef CHTBL_H
#define CHTBL_H
#include "pch.h"
#include "list.h"
#include <stdlib.h>
typedef struct CHTbL_
{
int buckets;
int(*h)(const void *key);
int(*match)(const void *key1, const void *key2);
void(*destory)(void *data);
int size;
List *table;
}CHTbL;
int chtbl_init(CHTbL *htbl, int buckets, int(*h)(const void *key),
int(*match)(const void *key1, const void *key2), void(*destory)(void *data));
void chtbl_destory(CHTbL *htbl);
int chtbl_insert(CHTbL *htbl,const void *data);
int chtbl_remove(CHTbL *htbl, void **data);
int chtbl_lookup(const CHTbL *htbl, void **data);
#define chtbl_size(htbl) ((htbl)->size)
#endif // !CHTBL_H
C++文件:
chtbl.cpp
#include "pch.h"
#include "list.h"
#include "chtbl.h"
#include <stdlib.h>
#include <string.h>
int chtbl_init(CHTbL *htbl, int buckets, int(*h)(const void *key),
int(*match)(const void *key1, const void *key2), void(*destory)(void *data))
{
int i;
if ((htbl->table = (List *)malloc(buckets * sizeof(List))) == NULL)
return -1;
htbl->buckets = buckets;
for (i = 0; i < htbl->buckets; i++)
list_init(&htbl->table[i], destory);
htbl->h = h;
htbl->match = match;
htbl->destory = destory;
htbl->size = 0;
return 0;
}
void chtbl_destory(CHTbL *htbl)
{
int i;
for (i = 0; i < htbl->buckets; i++)
{
list_destory(&htbl->table[i]);
}
free(htbl->table);
memset(htbl, 0, sizeof(CHTbL));
return;
}
int chtbl_insert(CHTbL *htbl, const void *data)
{
void *temp;
int bucket, retval;
temp = (void *)data;
if (chtbl_lookup(htbl, &temp) == 0)
return 1;
bucket = htbl->h(data) % htbl->buckets;
if ((retval = list_ins_next(&htbl->table[bucket], NULL, data)) == 0)
htbl->size++;
return retval;
}
int chtbl_remove(CHTbL *htbl, void **data)
{
ListElmt *element, *prev;
int bucket;
bucket=htbl->h(*data) % htbl->buckets;
prev = NULL;
for (element = list_head(&htbl->table[bucket]); element != NULL; element = list_next(element))
{
if (htbl->match(*data, list_data(element)))
{
if (list_rem_next(&htbl->table[bucket], prev, data) == 0)
{
htbl->size--;
return 0;
}
else
{
return -1;
}
}
prev = element;
}
return -1;
}
int chtbl_lookup(const CHTbL *htbl, void **data)
{
ListElmt *element;
int bucket;
bucket = htbl->h(*data) % htbl->buckets;
for (element = list_head(&htbl->table[bucket]); element != NULL; element = list_next(element))
{
if (htbl->match(*data, list_data(element)))
{
*data = list_data(element);
return 0;
}
}
return -1;
}
哈希函数:
#include "pch.h"
#include "chtbl.h"
int hashpjw(const void *key)
{
const char *ptr;
unsigned int val;
val = 0;
ptr = (char *)key;
while (*ptr!='\0')
{
unsigned int tmp;
val = (val << 4) + (*ptr);
if (tmp = (val & 0xf0000000))
{
val = val ^ (tmp >> 24);
val = val ^ tmp;
}
ptr++;
}
return val % 2;
}
调用过程
#pragma region 哈希表
CHTbL *hash=(CHTbL *)malloc(sizeof(CHTbL));
chtbl_init(hash,1, hashpjw, matchImp, NULL);
string s = "嘿嘿嘿";
chtbl_insert(hash, &s);
string s2 = "嘿嘿嘿2";
chtbl_insert(hash, &s2);
cout << hash->size << endl;
cout << *(string *)list_data(hash[1].table->head) << endl;
#pragma endregion
以上代码参考《算法精解:C语言描述(中文版)》