标签:
对于C语言而言,实现哈希表加深指针的运用。哈希表是典型空间换时间的算法,解决冲突有多种,以下采用链条式。
以下是本人造的轮子,做一个记录。
hash.c
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 #define HASHSIZE 101 6 struct nlist { 7 struct nlist *next; 8 char *name; 9 char *defn; 10 }; 11 12 static struct nlist *hashtab[HASHSIZE]; 13 14 unsigned char hash(char *s) 15 { 16 unsigned int hashval; 17 for (hashval = 0; *s != ‘\0‘; s++) { 18 hashval = hashval * 31 + *s; 19 } 20 return hashval % HASHSIZE; 21 } 22 23 struct nlist *lookup_hash(char *s) 24 { 25 struct nlist *np; 26 for (np = hashtab[hash(s)]; NULL != np; np = np->next) { 27 if (!strcmp(s, np->name)) { 28 return np; 29 } 30 } 31 return NULL; 32 } 33 34 struct nlist *insert_hash(char *name, char *defn) 35 { 36 struct nlist *np; 37 unsigned char hashval; 38 if (NULL == (np = lookup_hash(name))) { 39 np = (struct nlist *)malloc(sizeof(struct nlist)); 40 if (NULL == np || NULL == (np->name = strdup(name))) { 41 return NULL; 42 } 43 hashval = hash(name); 44 np->next = hashtab[hashval]; 45 hashtab[hashval] = np; 46 } 47 if (NULL == (np->defn = strdup(defn))) { 48 return NULL; 49 } 50 return np; 51 } 52 int remove_hash(char *name) 53 { 54 struct nlist *np, *prev = NULL; 55 for (np = hashtab[hash(name)]; NULL != np; np = np->next) { 56 if (!strcmp(name, np->name)) { 57 break; 58 } 59 prev = np; 60 } 61 if (NULL == np) { 62 return -1; 63 } 64 65 free((void *)np->defn); 66 free((void *)np->name); 67 if (NULL == prev) { 68 /*删除头链表数据*/ 69 hashtab[hash(name)] = np->next; 70 } 71 else { 72 prev->next = np->next; 73 } 74 free((void *)np); 75 return 0; 76 } 77 78 void printNode(struct nlist *np) 79 { 80 if (NULL != np) { 81 printf("%s %s\t", np->name, np->defn); 82 printNode(np->next); 83 } 84 } 85 86 void print() 87 { 88 unsigned char i; 89 for (i = 0; i < HASHSIZE; i++) { 90 printNode(hashtab[i]); 91 printf("\n"); 92 } 93 } 94 95 int main(int argc, char const **argv) 96 { 97 insert_hash("Kevin_Hwang", "Welcome!"); 98 insert_hash("test1", "This is the test1!"); 99 insert_hash("test2", "This is the test2!"); 100 insert_hash("test3", "This is the test3!"); 101 insert_hash("test4", "This is the test4!"); 102 remove_hash("test1"); 103 remove_hash("test4"); 104 insert_hash("test2", "The test4 has modified!"); 105 print(); 106 return 0; 107 }
链条哈希表算法插入一个数据思路是:
1:开辟一个初始数组作为哈希表(如果空间没问题越大越好);
2:根据新插入的数据计算出对应哈希值作为哈希表的索引,若对应索引号的哈希序号没数据则直接插入。若已有数据冲突,则把此哈希序号的值指向
新插入数据(hashtab[hashval] = np),并把新插入数组的下一个链条指针指向旧数据(np->next = hashtab[hashval];)。
删除一个数据时,以上程序只要注意检查要删除的数据是否是链表头数据,中间和末端不用做特别处理。
标签:
原文地址:http://www.cnblogs.com/kevinhwang/p/5594216.html