分离链接散列表C语言实现实例
/* hash_sep.h */ #ifndef _HASH_SEP_H #define _HASH_SEP_H #define MIN_TABLE_SIZE 5 struct list_node; typedef struct list_node *position; struct hash_tbl; typedef struct hash_tbl *hash_table; typedef unsigned int hash_index; hash_index hash(const char *key, int table_size); hash_table initialize_table(int table_size); void destroy_table(hash_table h); position find(char *key, hash_table h); void insert(char *key, hash_table h); char *retrieve(position p); #endif
/* hash_sep.c */ #include "hash_sep.h" #include <string.h> #include <stdio.h> #include <stdlib.h> #include <error.h> struct list_node { char element[100]; position next; }; typedef position list; /* List *the_lists will be an array of lists, allocated later */ /* the lists use headers (for simplicity), */ /* though this wastes space */ struct hash_tbl { int table_size; list *the_lists; }; hash_index hash(const char *key, int table_size) { unsigned int hash_val = 0; while(*key != '\0') hash_val = (hash_val << 5) + *key++; return hash_val % table_size; } hash_table initialize_table(int table_size) { hash_table h; int i; if(table_size < MIN_TABLE_SIZE) { printf("Table size too small"); return NULL; } /* allocate table */ h = malloc(sizeof(struct hash_tbl)); if(h == NULL) { perror("malloc"); exit(1); } h->table_size = table_size; /* allocate array of lists */ h->the_lists = malloc(sizeof(list) * h->table_size); if(h->the_lists == NULL) { perror("malloc"); exit(1); } /* allocate list headers */ for(i = 0; i < h->table_size; i++) { h->the_lists[i] = malloc(sizeof(struct list_node)); if(h->the_lists[i] == NULL) { perror("malloc"); exit(1); } else h->the_lists[i]->next = NULL; } return h; } position find(char *key, hash_table h) { position p; list l; l = h->the_lists[hash(key, h->table_size)]; p = l->next; while(p != NULL && strcmp(p->element, key)) p = p->next; return p; } void insert(char *key, hash_table h) { position pos; position new_cell; list l; pos = find(key, h); if(pos == NULL) { new_cell = malloc(sizeof(struct list_node)); if(new_cell == NULL) { perror("malloc"); exit(1); } else { l = h->the_lists[hash(key, h->table_size)]; new_cell->next = l->next; strcpy(new_cell->element, key); l->next = new_cell; } } } void destroy_table(hash_table h) { int i; if(h != NULL) { for(i = 0; i < h->table_size; i++) free(h->the_lists[i]); free(h->the_lists); free(h); } } char * retrieve(position p) { return p->element; }
/* hash_test.c */ #include <stdio.h> #include "hash_sep.h" int main(void) { position p1; position p2; position p3; char *tmp1; char *tmp2; char *tmp3; char array1[] = "zhu"; char array2[] = "yong"; char array3[] = "chang"; hash_table htp; htp = initialize_table(10); insert(array1, htp); insert(array2, htp); insert(array3, htp); p1 = find("zhu", htp); p2 = find("yong", htp); p3 = find("chang", htp); tmp1 = retrieve(p1); tmp2 = retrieve(p2); tmp3 = retrieve(p3); printf("\n%s %s %s\n\n", tmp1, tmp2, tmp3); destroy_table(htp); }
实例测试结果: