C++之 哈希表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zh1204190329/article/details/82937700

C/C++哈希表、字典表
将字符串的key,转成整数,使用整数找到对应的value;**
Hash算法将字符串转成整数,同样的Hash值得 key:value会放到一个集合里面,由于Hash能使得不同的字符串尽量有不同的整数值(仍然有重复);
将海量的数据,按照HASH值分成不同的集合,先找集合,再找key–>value,大大提高效率;

#include <iostream>
#include <string.h>
#include <stack>
#include <set>
#include <string>
#include <bits/stdc++.h>
#include <cstdio>
#include <cstdlib>


using namespace std;

#define my_malloc malloc
#define my_free free


struct hash_node{
	char *key;   // key of hash
	void* node;   // value of hash
	struct hash_node *next;
};

struct hash_table{
	struct hash_node** hash_set;  // pointer of set
	int n; // number of set in hash_table
};

struct hash_table* create_hash_table(int n)
{
	struct hash_table * t = (struct hash_table *)my_malloc(sizeof(struct hash_table));
	memset(t, 0, sizeof(struct hash_table));

	// space of n sets, storage pointer of list head
	t->hash_set = (struct hash_node **)my_malloc(n * sizeof(struct node *));  // allocate memory of struct set
	memset(t->hash_set, 0 , sizeof(struct hash_node*) * n);  // initialize memory
	t->n = n;
	return t;
}

static unsigned int hash_index(char *str)
{
	register unsigned int h;
	register unsigned char *p;

	for (h = 0, p = (unsigned char *)str; *p; p++)
		h = 31 * h + *p;

	return h;
}

// insert key:value, not judge whether the value is repeating or not
void hash_insert(struct hash_table* t, char *key, void* value)
{
	struct hash_node* node = (struct hash_node*)my_malloc(sizeof(struct hash_node));
	memset(node, 0, sizeof(struct hash_node));
	node->key = _strdup(key);
	node->node = value;

	int index = (hash_index(key) % t->n);
	struct hash_node* header = t->hash_set[index];

	node->next = header;
	t->hash_set[index] = node;
}

// delete table
void hash_delete(struct hash_table *t, char *key)
{
	int index = (hash_index(key) % t->n);
	struct hash_node** walk = &(t->hash_set[index]);

	while(*walk)
	{
		if (strcmp((*walk)->key, key) == 0)
		{
			struct hash_node* rm_node = *walk;
			*walk = (*walk)->next;

			rm_node->next = NULL;

			// free key, hash_node
			my_free(rm_node->key);
			my_free(rm_node);
		}
		else
		{
			walk = &((*walk)->next);
		}
	}
}

// clear all data in hash table
void hash_clear(struct hash_table * t)
{
	for (int i = 0; i < t->n; i++)
	{
		struct hash_node* walk = t->hash_set[i];
		t->hash_set[i] = NULL;

		while(walk)
		{
			struct hash_node* rm_node = walk;
			walk = walk->next;
			rm_node->next = NULL;

			my_free(rm_node->key);
			my_free(rm_node);
		}
	}
}

// destory hash
void destory_hash_table(struct hash_table* t)
{
	// clear all data
	hash_clear(t);
	if(t->hash_set)
	{
		my_free(t->hash_set);
		t->hash_set = NULL;
	}

	my_free(t);
}


// modify data , key:value
void hash_set(struct hash_table *t, char *key, void* value)
{
	// return set which the key belongs to , by using hash table
	int index = (hash_index(key) % t->n);
	struct hash_node** walk = &(t->hash_set[index]);

	while(*walk)
	{
		if (strcmp((*walk)->key, key) == 0)
		{
			(*walk)->node = value;
			return;
		}
		walk = &((*walk)->next);
	}

	// there is no key and value, then new
	struct hash_node* Node = (struct hash_node*)my_malloc(sizeof(struct hash_node));
	memset(Node, 0, sizeof(struct hash_node));
	Node->key = _strdup(key);
	Node->node = value;
	*walk = Node;
}


// find value in hash table
void * hash_find(struct hash_table* t, char * key)
{
	// use hash to return the set which the key belongs to
	int index = (hash_index(key) % t->n);
	struct hash_node* walk = (t->hash_set[index]);

	while(walk)
	{
		if (strcmp((walk)->key, key) == 0)
		{
			return walk->node;
		}
	}
	return NULL;

}



int main()
{
	cout << "-----------" << endl;
	struct hash_table* t = create_hash_table(1024);

	hash_insert(t, (char *)"xiaoming", (void *)12);
	hash_insert(t, (char *)"xiaomeng", (void *)36);
	hash_insert(t, (char *)"xiaozhao", (void *)"cqupt");

	int ret = (int)hash_find(t, (char *)"xiaoming"); // find vaule in hash table
	printf("xiaoming = > %d\n", ret);

	char *address = (char *)hash_find(t, (char *)"xiaozhao");
	printf("address = %s\n", address);

	void* value = (void*)hash_find(t, (char *)"tttt");
	if (value == NULL)
		printf("can not find value, %s\n", (char *)value);

	hash_delete(t,(char *) "xiaomeng");

	value =(void*)hash_find(t, (char *)"xiaomeng");
	if (value == NULL)
		printf("can not find value of key equals to 'xiaomeng', %s\n", (char *)value);

	destory_hash_table(t);


	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zh1204190329/article/details/82937700