版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}