散列表
查询速度非常快的数据结构,查询时间复杂度是O(1)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#ifndef _COMMON_H_ #define _COMMON_H_ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #endif
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#ifndef _HASH_H_ #define _HASH_H_ typedef unsigned int u_int; typedef struct hash_s hash_t; typedef u_int (*hash_func_t)(u_int bucket_size, const void *key, u_int key_size); hash_t * hash_table_create(u_int bucket_size, hash_func_t hash_func); void *hash_lookup_entry(hash_t *hash_table, void* key, u_int key_size); void hash_add_entry(hash_t *hash_table, void *key, u_int key_size, void* value, u_int value_size); void hash_free_entry(hash_t *hash_table, void *key, u_int key_size); void travel(hash_t * table); #endif
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include "hash.h" #include "common.h" typedef struct hash_node_s { void *key; void *value; struct hash_node_s *next; }hash_node_t; struct hash_s { u_int bucket_size; hash_func_t hash_func; hash_node_t **pnodes; }; hash_t * hash_table_create(u_int bucket_size, hash_func_t hash_func) { hash_t * hash_table; hash_table = (hash_t *)malloc(sizeof(hash_t)); hash_table->bucket_size = bucket_size; hash_table->hash_func = hash_func; hash_table->pnodes = (hash_node_t **)malloc(bucket_size * sizeof(hash_node_t *)); memset(hash_table->pnodes, 0, bucket_size * sizeof(hash_node_t *)); return hash_table; } void *hash_lookup_entry(hash_t *hash_table, void* key, u_int key_size) { u_int index = hash_table->hash_func(hash_table->bucket_size, key, key_size); assert(index < hash_table->bucket_size); hash_node_t *pnode = hash_table->pnodes[index]; while (pnode) { if (0 == memcmp(pnode->key, key, key_size)) { return pnode->value; } pnode = pnode->next; } return NULL; } void hash_add_entry(hash_t *hash_table, void *key, u_int key_size, void* value, u_int value_size) { u_int index = hash_table->hash_func(hash_table->bucket_size, key, key_size); assert(index < hash_table->bucket_size); hash_node_t *newnode = (hash_node_t*)malloc(sizeof(hash_node_t)); newnode->key = malloc(key_size); memcpy(newnode->key, key, key_size); newnode->value = malloc(value_size); memcpy(newnode->value, value, value_size); if (hash_table->pnodes[index] == NULL) { newnode->next = NULL; hash_table->pnodes[index] = newnode; } else { newnode->next = hash_table->pnodes[index]->next; hash_table->pnodes[index]->next = newnode; } } void hash_free_entry(hash_t *hash_table, void *key, u_int key_size) { u_int index = hash_table->hash_func(hash_table->bucket_size, key, key_size); assert(index < hash_table->bucket_size); hash_node_t *pnode = hash_table->pnodes[index]; if (pnode != NULL) { if (memcmp(pnode->key, key, key_size) == 0) { hash_node_t **tmp = &hash_table->pnodes[index]; *tmp = pnode->next; free(pnode->key); free(pnode->value); free(pnode); } else { hash_node_t *tmp = pnode; while (pnode && memcmp(pnode->key, key, key_size) != 0) { tmp = pnode; pnode = pnode->next; } if (pnode) { tmp->next = pnode->next; free(pnode->key); free(pnode->value); free(pnode); } } } } void travel(hash_t * table) { for (int i = 0; i < table->bucket_size; i++) { hash_node_t *pnode = table->pnodes[i]; while (pnode) { printf("%s ", (char*)pnode->key); pnode = pnode->next; } printf("\n"); } printf("\n"); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include "hash.h" #include "common.h" u_int BKDRHash(u_int bucket_size, const void *key, u_int key_size) { size_t hash = 0; const char* tmp = key; int index = 0; char ch = -1; while (index != key_size) { ch = tmp[index]; hash = hash * 131 + ch; index++; } return hash % bucket_size; } int main() { hash_t * table = hash_table_create(3, BKDRHash); char * arr[][2] = {{"baidu", "liyanhong"}, {"ali", "mayun"}, {"tencent", "mahuateng"}, {"toutiao", "zhangyiming"}, {"meituan","wangxing"}, {"didi","chengwei"}}; for (int i = 0; i < 6; i++) { hash_add_entry(table, arr[i][0], strlen(arr[i][0]), arr[i][1], strlen(arr[i][1])); } travel(table); char* company = "ali"; char* ret = hash_lookup_entry(table, company, strlen(company)); if (ret) { printf("%s\n", ret); } char* tc = "baidu"; hash_free_entry(table, tc, strlen(tc)); travel(table); hash_add_entry(table, arr[2][0], strlen(arr[2][0]), arr[2][1], strlen(arr[2][1])); travel(table); return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
table: main.o hash.o gcc -g -o table main.o hash.o main.o: main.c gcc -c -g main.c hash.o: hash.c gcc -c -g hash.c .PHONY:clean clean: rm -f table main.o hash.o