C++实现哈希表

由于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语言描述(中文版)》

猜你喜欢

转载自blog.csdn.net/qq_39628933/article/details/84141960