C语言-简单哈希表(hash table)

时间:2023-03-08 20:14:10

  腾讯三面的时候,叫我写了个哈希表,当时紧张没写好···结果跪了···

  回来后粪发涂墙,赶紧写了一个!

  什么都不说了···先让我到厕所里面哭一会···

  %>_<%

  果然现场发挥,以及基础扎实才是important的!  

  用链地址法解决冲突的哈希表(C语言,VS2008编写、测试):

 #include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h> struct node {
int count; // count the same value
char *value;
node *next;
}; // 使用链地址法解决冲突
struct hash_table {
int size; // table size
node **list; // 链表队列一条链为一个散列位置
}; //==================================================//
// declare int hash_func(char *str, int tableSize);
hash_table *hash_table_init(int tableSize);
node *hash_table_new_node(char *str, int len);
int hash_table_insert(char *str, struct hash_table * head);
node *hash_table_find(char *str, struct hash_table * head);
void hash_table_clear(struct hash_table * head);
void hash_table_print(hash_table *head); //==================================================//
// realize // hash function: return the position of str in the hash table
int hash_func(char *str, int tableSize) {
unsigned int hashVal = ; while (*str != '\0')
hashVal += (hashVal << ) + *str++; return hashVal % tableSize;
} // init & create hash table
hash_table *hash_table_init(int tableSize) {
hash_table *head; head = (hash_table *)malloc(sizeof(hash_table));
if (NULL == head)
return NULL;
// 元素总数量尽可能为素数,以保证mod尽可能均匀
head->size = tableSize; // 链表队列中,一条链为一个散列位置
head->list = (node **)malloc(sizeof(node *) * tableSize); // initialize each hash list
int i;
for (i = ; i < head->size; i++)
head->list[i] = NULL; return head;
} // return one new node
node *hash_table_new_node(char *str, int len) {
node *newNode = (node *)malloc(sizeof(node));
newNode->count = ;
newNode->next = NULL;
newNode->value = (char *)malloc(len + );
memset(newNode->value, , len + );
memcpy(newNode->value, str, len); return newNode;
} // insert one node into hash table
int hash_table_insert(char *str, hash_table *head) {
int len = strlen(str);
// get str's position in the hash table
int pos = hash_func(str, head->size); printf("[insert] %s at pos: %d\n", str, pos); // locate list
node *q = head->list[pos], *p = head->list[pos];
for ( ; p != NULL; p = p->next) {
if (memcmp(p->value, str, len) == ) {
p->count++; // found the same value, count+1
return pos;
}
q = p; // store the previous node
} // if not found, then insert one new node
node *newNode = hash_table_new_node(str, len);
/*
//===================================================================//
// method 1:
// TODO: 如果是字符串不同,但是哈希值一样呢???貌似没考虑到这种情况
// insert into the head of list
newNode->next = head->list[pos];
head->list[pos] = newNode;
*/
//===================================================================//
// method 2:
// insert into the tail of list
// 由于p指向了NULL,所以要插入链表尾的话,就必须增加一个变量q记录p前一个节点位置
if (NULL == q) {
newNode->next = head->list[pos];
head->list[pos] = newNode;
} else {
q->next = newNode;
newNode->next = NULL;
} return pos;
} // find the node which stored str & return it
node *hash_table_find(char *str, hash_table *head) {
if (NULL == head)
return NULL; int pos = hash_func(str, head->size);
node *p = head->list[pos]; int len = strlen(str); for ( ; p != NULL; p = p->next)
if (memcmp(p->value, str, len) == )
break;//return p; // found & return return p; //return NULL;
} // clear the whole hash table
void hash_table_clear(hash_table *head) {
if (NULL == head)
return; node *p = NULL, *q = NULL; int i;
for (i = ; i < head->size; i++) {
p = head->list[i];
while (p != NULL) {
p->count = ; // TODO: test
q = p->next;
// free value
if (p->value) {
free(p->value);
p->value = NULL;
}
// free current node
if (p) {
free(p);
p = NULL;
}
// point to next node
p = q;
}
}
// free list
if (head->list) {
free(head->list);
head->list = NULL;
}
// free head
if (head) {
free(head);
head = NULL;
}
} // print the whole hash table
void hash_table_print(hash_table *head) {
if (NULL == head) {
printf("hash table is NULL! \n");
return;
} int i;
node *p = NULL; for ( i = ; i < head->size; i++) {
p = head->list[i];
printf("//============list %d============//\n", i);
while (p != NULL) {
if (p->value)
printf("%s:%d ", p->value, p->count);
else
printf("(NULL):(0) ");
p = p->next;
}
printf("\n");
}
} // test
int main() {
// create
hash_table *head = hash_table_init(); // insert
hash_table_insert("test 1", head);
hash_table_insert("test 2", head);
hash_table_insert("test 2", head);
hash_table_insert("test 3", head);
hash_table_insert("test 4", head); hash_table_print(head); // find
node *find = hash_table_find("test 2", head);
printf("\n[Find] %s:%d\n\n", find->value, find->count); // clear
hash_table_clear(head); hash_table_print(head); // create
head = hash_table_init(); // insert
hash_table_insert("test 1", head);
hash_table_insert("test 2", head);
hash_table_insert("test 2", head);
hash_table_insert("test 3", head);
hash_table_insert("test 4", head); hash_table_print(head); return ;
}