對於C語言而言,實現哈希表加深指針的運用。哈希表是典型空間換時間的算法,解決衝突有多種,如下采用鏈條式。算法
如下是本人造的輪子,作一個記錄。數組
hash.cspa
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:開闢一個初始數組做爲哈希表(若是空間沒問題越大越好);code
2:根據新插入的數據計算出對應哈希值做爲哈希表的索引,若對應索引號的哈希序號沒數據則直接插入。若已有數據衝突,則把此哈希序號的值指向blog
新插入數據(hashtab[hashval] = np),並把新插入數組的下一個鏈條指針指向舊數據(np->next = hashtab[hashval];)。索引
刪除一個數據時,以上程序只要注意檢查要刪除的數據是不是鏈表頭數據,中間和末端不用作特別處理。rem