user-0 提问: hash表，请帮忙改进！！

回复:
user: user-0
content: 现有一个问题请教： struct element__ i_element; Element element = &i_element; 这里为什么要这么做？ 如果简单的声明一个Element element;   /* ** file hash.h */ #ifndef HASH_H__ #define HASH_H__  #ifdef _cplusplus extern "C"{ #endif   typedef struct element__*     Element; typedef struct jhashtable__*  JHashTable;  typedef unsigned int (*hash_func)    (Element element, int capcity); typedef int          (*hash_compare) (Element element1, Element element2); typedef void         (*hash_insert)  (JHashTable hashtable, Element element); //typedef Element      (*hash_get)     (JHashTable hashtable, Element element); typedef void         (*hash_destory) (JHashTable hashtable);  typedef struct hash_method__  {     hash_func    hash;     hash_compare compare;     hash_insert  insert;     hash_destory destory; }Hash_method;   struct element__ {     void*             data;    ///<  兼容内置类型和复杂类型     struct element__* next; };  struct jhashtable__ {     int          capcity;     Element*     lists;     Hash_method  method;     };  /* **创建一个JHashTable，对于不同的类型，需不同的hash函数和compare函数，由用户自定义 */ JHashTable hash_create(int capcity, hash_compare compare, hash_func hash);  #ifdef _cplusplus } #endif  #endif /* ** file hash.c */ #include "hash.h" #include <stdio.h> #include <stdlib.h>  static unsigned int hash_capcity(unsigned int size)                                   {                                                                                        const int primes[] =     {       11,       19,       37,       73,       109,       163,       251,       367,       557,       823,       1237,       1861,       2777,       4177,       6247,       9371,       14057,       21089,       31627,       47431,       71143,       106721,       160073,       240101,       360163,       540217,       810343,       1215497,       1823231,       2734867,       4102283,       6153409,       9230113,       13845163,       20767751,       31151639,       46727459,       70091201,       105136807,       157705213,       236557861,       354836813,       532255237,       798382861,       1197574073,       1796361143,       2000000011,     };     int i;     for(i = 0; primes[i] < 2000000000; i++)     {         if(primes[i] > size)         break;     }     return primes[i];    }   static void insert( JHashTable hashtable,Element element) {     Element current;     unsigned int index = hashtable->method.hash(element, hashtable->capcity);     {         current = (Element)malloc(sizeof(struct element__));         if(current)         {             current->data = element->data;             current->next = hashtable->lists[index];             hashtable->lists[index] = current;         }     } }  static void destory(JHashTable hashtable) {     int i;     for(i = 0;i<hashtable->capcity; i++)     {         Element element  = hashtable->lists[i];         Element temp;          while(element!= NULL)         {             temp = element->next;             free(element);             element= temp;         }     }     free(hashtable->lists);     free(hashtable); }  JHashTable hash_create(int capcity, hash_compare compare, hash_func hash) {     JHashTable hashtable;     int i = 0;     hashtable= (JHashTable)malloc(sizeof(struct jhashtable__));     if(hashtable)     {         hashtable->capcity = hash_capcity(capcity); ///<  计算表的容量         hashtable->lists = (Element*)malloc(sizeof(Element)*hashtable->capcity);  ///<  lists[capcity]         if(hashtable->lists)         {             for(i=0;i<hashtable->capcity;i++)             {                 hashtable->lists[i] = (Element)malloc(sizeof(struct element__));                 if(hashtable->lists[i])                 {                     hashtable->lists[i]->next = NULL;                     hashtable->lists[i]->data = 0;                 }             }         }              }     hashtable->method.compare = compare;     hashtable->method.hash = hash;     hashtable->method.insert = insert;     hashtable->method.destory = destory;     return hashtable; } /* ** file hash_test.c */ #include "hash.h" #include <stdio.h> #include <string.h>  static unsigned int RShash(char *str) {     unsigned int b = 378551;     unsigned int a = 63689;     unsigned int hash = 0;      while(*str)     {        hash = hash * a + (*str++);        a *= b;     }     return (hash & 0x7FFFFFFF); }  static unsigned int hash_int(Element element, int capcity) {     int p = (int)element->data;     return p%capcity; }  static int compare_int (Element element1, Element element2) {     int p1 = (int)element1->data;     int p2 = (int)element2->data;     return p1 - p2; }  static unsigned int hash_string(Element element, int capcity) {     char* p = (char*)element->data;     return RShash(p)%capcity; }  static int compare_string (Element element1, Element element2) {     char* p1 = (char*)element1->data;     char* p2 = (char*)element2->data;     return RShash(p1) - RShash(p2); } int main() {     JHashTable hashtable;     struct element__ i_element;     Element element = &i_element;     int i = 0;     printf("---------test int hash------------!!!!\n");     hashtable = hash_create(15, compare_int, hash_int);         int array[] = {19,14,23,01,68,20,84,27,55,11,10,79};     int len = sizeof(array)/sizeof(array[0]);             for(i=0;i<len;i++)     {         element->data = array[i];         hashtable->method.insert(hashtable, element);     }     for(i = 0; i < hashtable->capcity; i++)     {         element = hashtable->lists[i];         while(element)         {             printf("address=%d value = %d\n", i, element->data);             element= element->next;         }     }      printf("---------test string hash------------!!!!\n");     element = &i_element;     char* string[] = {"hello", "word", "china", "USA", "green"};     hashtable = hash_create(10, compare_string, hash_string);     len = sizeof(string)/sizeof(string[0]);     for(i = 0; i < len; i++)     {         element->data = string[i];         hashtable->method.insert(hashtable, element);     }     for(i = 0; i < hashtable->capcity; i++)     {         element = hashtable->lists[i];         while(element)         {             printf("address=%d value = %s\n", i, element->data);             element= element->next;         }     }      return 0; } /* **  结果如下： [root@gnos-x64-dev wx]# ./hash  ---------test int hash------------!!!! address=0 value = 19 address=0 value = 0 address=1 value = 20 address=1 value = 1 address=1 value = 0 address=2 value = 0 address=3 value = 79 address=3 value = 0 address=4 value = 23 address=4 value = 0 address=5 value = 0 address=6 value = 0 address=7 value = 0 address=8 value = 27 address=8 value = 84 address=8 value = 0 address=9 value = 0 address=10 value = 10 address=10 value = 0 address=11 value = 11 address=11 value = 68 address=11 value = 0 address=12 value = 0 address=13 value = 0 address=14 value = 14 address=14 value = 0 address=15 value = 0 address=16 value = 0 address=17 value = 55 address=17 value = 0 address=18 value = 0 ---------test string hash------------!!!! 5 address=0 value = green address=0 value = (null) address=1 value = USA address=1 value = word address=1 value = (null) address=2 value = hello address=2 value = (null) address=3 value = (null) address=4 value = (null) address=5 value = (null) address=6 value = (null) address=7 value = china address=7 value = (null) address=8 value = (null) address=9 value = (null) address=10 value = (null) */

user: user-1
content: 引用 5 楼 u012889234 的回复:[quote=引用 4 楼 neustar1 的回复:] 如果不想用模板的话，最好定义一个接口，譬如 class IHashable { public: int Hash(JHashTable* pHashTable);//计算其哈希值 } 然后void*指针指向IHashable，就可以兼容复杂类型了，至于基本类型的话，建议另外定义一个共用体成员来保存。  我定义的 struct node__ {    void*   data;    struct node__* next; }; 这里的data就是void* 类型的，在这里兼容类型不可以吗？？[/quote] 不好意思，如果是c的话，就不能用模板了。。。 你这里void也可以兼容基本类型，但是你要用一个变量区分一下基本类型和复杂类型。

user: user-0
content: 引用 4 楼 neustar1 的回复:如果不想用模板的话，最好定义一个接口，譬如 class IHashable { public: int Hash(JHashTable* pHashTable);//计算其哈希值 } 然后void*指针指向IHashable，就可以兼容复杂类型了，至于基本类型的话，建议另外定义一个共用体成员来保存。  我定义的 struct node__ {    void*   data;    struct node__* next; }; 这里的data就是void* 类型的，在这里兼容类型不可以吗？？

user: user-1
content: 如果不想用模板的话，最好定义一个接口，譬如 class IHashable { public: int Hash(JHashTable* pHashTable);//计算其哈希值 } 然后void*指针指向IHashable，就可以兼容复杂类型了，至于基本类型的话，建议另外定义一个共用体成员来保存。

user: user-0
content: 引用 2 楼 neustar1 的回复:[quote=引用 1 楼 u012889234 的回复:] 来者都给分！！！！ 可以考虑使用模板[/quote] c 语言怎么设计模板的？？请指教！！

user: user-1
content: 引用 1 楼 u012889234 的回复:来者都给分！！！！ 可以考虑使用模板

user: user-0
content: 来者都给分！！！！