算法导论代码 第11章 散列表
2011-12-30 15:55
323 查看
第11章 散列表
11.2 散列表
#include <stdio.h> #include <stdlib.h> /*通过链接法解决碰撞*/ typedef struct hash_chain_type *hash; typedef struct list_type *list; struct list_node { void *key; struct list_node *prev; struct list_node *next; }; struct list_type { struct list_node *head; }; struct hash_chain_type { list *list_array; int (*get_value) (const void *); int num; }; void list_node_ini(struct list_node *p, void *key) { p->key = key; p->prev = NULL; p->next = NULL; } list list_create() { list l = malloc(sizeof(struct list_type *)); l->head = NULL; return l; } void list_destroy(list l, void (*free_key) (void *)) { struct list_node *x = l->head; while (x != NULL) { struct list_node *del = x; x = x->next; free_key(del->key); free(del); } free(l); } struct list_node *list_search(list l, void *k, int (*comp) (const void *, const void *)) { struct list_node *x = l->head; while (x != NULL && comp(x->key, k) != 0) { x = x->next; } return x; } void list_insert(list l, struct list_node *x) { x->next = l->head; if (l->head != NULL) { l->head->prev = x; } l->head = x; x->prev = NULL; } void list_delete(list l, struct list_node *x) { if (x->prev != NULL) { x->prev->next = x->next; } else { l->head = x->next; } if (x->next != NULL) { x->next->prev = x->prev; } } hash hash_create(int num, int (*get_value) (const void *)) { hash h = malloc(sizeof(struct hash_chain_type)); h->num = num; h->get_value = get_value; h->list_array = malloc(sizeof(list) * num); for (int i = 0; i < num; i++) { h->list_array[i] = list_create(); } return h; } void hash_destroy(hash h, void (*free_key) (void *)) { for (int i = 0; i < h->num; i++) { list_destroy(h->list_array[i], free_key); }; free(h->list_array); free(h); } int hash_value(hash h, int key) { return key % h->num; } void hash_insert(hash h, struct list_node *x) { int key = h->get_value(x); list l = h->list_array[hash_value(h, key)]; list_insert(l, x); } struct list_node *hash_search(hash h, int key, int (*comp) (const void *, const void *)) { list l = h->list_array[hash_value(h, key)]; return list_search(l, &key, comp); } void hash_delete(hash h, struct list_node *x) { if (x == NULL) return; int key = h->get_value(x); list l = h->list_array[hash_value(h, key)]; list_delete(l, x); } /*用于list_node的key成员的比较函数*/ int cmp_int(const void *p1, const void *p2) { const int *pa = p1; const int *pb = p2; if (*pa < *pb) return -1; if (*pa == *pb) return 0; return 1; } /*从list_node类型指针中取得关键字的整数值*/ int get_value(const void *x) { const struct list_node *p = x; const int *ip = p->key; return *ip; } int main() { hash h = hash_create(10,get_value); for (int i = 0; i < 10; i++) { struct list_node *x = malloc(sizeof(struct list_node)); int *p = malloc(sizeof(int)); *p = i; list_node_ini(x, p); printf("%d ", *p); hash_insert(h, x); } printf("\n"); int k = 0; struct list_node *x = hash_search(h, k, cmp_int); printf("查找关键字:%d的结果:%s\n", k, x != NULL ? "成功" : "失败"); if (x != NULL) { hash_delete(h, x); free(x->key); free(x); x = hash_search(h, k, cmp_int); printf("删除关键字:%d的结果:%s\n", k, x == NULL ? "成功" : "失败"); } hash_destroy(h, free); return 0; }
11.4 开放地址法
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct hash_open_addressing_type *hash; #define NIL ((void*)-1) #define DELETED ((void*)-2) struct hash_open_addressing_type { void **array; int num; int (*hash_fun) (hash, int, int); int (*get_value) (const void *); }; hash hash_create(int num, int (*hash_fun) (hash, int, int), int (*get_value) (const void *)) { hash h = malloc(sizeof(struct hash_open_addressing_type)); h->num = num; h->array = malloc(sizeof(void *) * num); for (int i = 0; i < h->num; i++) h->array[i] = NIL; h->hash_fun = hash_fun; h->get_value = get_value; return h; } void hash_destroy(hash h, void (*free_key) (void *)) { for (int i = 0; i < h->num; i++) { if (h->array[i] != NIL && h->array[i] != DELETED) { free_key(h->array[i]); } } free(h->array); free(h); } int hash_insert(hash h, void *p) { int key = h->get_value(p); int i = 0; int j = 0; do { j = h->hash_fun(h, key, i); if (h->array[j] == NIL || h->array[j] == DELETED) { h->array[j] = p; return j; } else { i++; } } while (i < h->num); return -1; } /*返回槽的索引*/ int hash_search(hash h, int key) { int i = 0; int j = 0; do { j = (h->hash_fun) (h, key, i); if (h->array[j] != DELETED) { int value = h->get_value(h->array[j]); if (value == key) { return j; } } ++i; } while (h->array[j] != NIL && i < h->num); return -1; } /*返回槽的索引*/ int hash_delete(hash h, int key) { int i = hash_search(h, key); if (i != -1) { h->array[i] = DELETED; } return i; } int hash_fun_linear(hash h, int key, int i) { int h1 = key % h->num; return (h1 + i) % h->num; } int hash_fun_quadratic(hash h, int key, int i) { int h1 = key % h->num; return (h1 + i + i * i) % h->num; } int hash_fun_double_hash(hash h, int key, int i) { int h1 = key % h->num; int h2 = key % h->num + 1; return (h1 + i * h2) % h->num; } /*从存到hash表里的类型指针中取得关键字的整数值*/ int get_value(const void *x) { const int *ip = x; return *ip; } int main() { hash h = hash_create(10, hash_fun_double_hash, get_value); for (int i = 0; i < 10; i++) { int *p = malloc(sizeof(int)); *p = i; printf("%d ", *p); hash_insert(h, p); } printf("\n"); int k = 0; int pos = hash_search(h, k); printf("查找关键字:%d的结果:%s\n", k, pos != -1 ? "成功" : "失败"); int *p = h->array[pos]; int delete_key = get_value(p); hash_delete(h, delete_key); free(p); pos = hash_search(h, k); printf("删除关键字:%d的结果:%s\n", k, pos == -1 ? "成功" : "失败"); hash_destroy(h, free); return 0; }
相关文章推荐
- 《算法导论》第11章 散列表 (1)直接寻址表
- 《算法导论》第11章 散列表 (1)直接寻址表
- 算法导论-第11章-散列表
- 《算法导论》第11章 散列表 (1)直接寻址表
- 《算法导论》第11章 散列表 (2)散列表
- 《算法导论》第11章 散列表 (2)散列表
- 《算法导论》第11章 散列表 (2)散列表
- 算法导论 第11章 散列表
- 《算法导论》读书笔记之第11章 散列表
- 《算法导论》第11章 散列表 (2)散列表
- 算法导论答案 第11章:散列表
- 算法导论第11章 散列表(哈希表)
- 《算法导论》第11章 散列表 (3)开放寻址
- 《算法导论》学习总结 — 10. 第10章(略) && 第11章 散列表
- 《算法导论》第11章 散列表 (3)开放寻址
- 算法导论-第11章-散列表
- 算法导论-第11章-散列表-11.1-4 大数组的直接寻址表
- 《算法导论》第11章 散列表 (3)开放寻址
- 《算法导论》第11章 散列表 (3)开放寻址
- 《算法导论》笔记 第11章 11.2 散列表