c语言实现通用数据结构:通用集合(HashSet)

这是在通用链表的基础上实现的集合,关于链表的实现参见:http://blog.csdn.net/swwlqw/article/details/22498833

注意集合中只存储了指针,没有储存实际的数据。

对于新的数据类型来说,需要自定义HashCode函数和equal函数。

下面还给出了几个常见的hashCode函数和equal函数。


(1)HashCode函数

头文件

[cpp]  view plain  copy
  1. /************************* 
  2. *** File myHashCode.h 
  3. **************************/  
  4. #ifndef MYHASHCODE_H_INCLUDED  
  5. #define MYHASHCODE_H_INCLUDED  
  6.   
  7. #include   
  8.   
  9. #define HASHCODE_MULT 31  
  10.   
  11. //默认的hashCode  
  12. int myHashCodeDefault(void * a);  
  13.   
  14. //int类型hashCode  
  15. int myHashCodeInt(void * a);  
  16.   
  17. //char类型的hashCode  
  18. int myHashCodeChar(void * a);  
  19.   
  20. //string类型的hashCode  
  21. int myHashCodeString(void * a);  
  22.   
  23. #endif // MYHASHCODE_H_INCLUDED  


源文件

[cpp]  view plain  copy
  1. /************************* 
  2. *** File myHashCode.c 
  3. **************************/  
  4. #include "myHashCode.h"  
  5.   
  6. //默认的hashCode  
  7. int myHashCodeDefault(void * a)  
  8. {  
  9.     return (int) a;  
  10. }  
  11.   
  12. //int类型hashCode  
  13. int myHashCodeInt(void * a)  
  14. {  
  15.     int * aa = (int *) a;  
  16.     return *aa;  
  17. }  
  18.   
  19. //char类型的hashCode  
  20. int myHashCodeChar(void * a)  
  21. {  
  22.     char *aa = (char *) a;  
  23.     return *aa;  
  24. }  
  25.   
  26. //string类型的hashCode  
  27. int myHashCodeString(void * a)  
  28. {  
  29.     int re = 0;  
  30.     char *aa = (char *) a;  
  31.     while (*aa)  
  32.     {  
  33.         re += HASHCODE_MULT * *aa;  
  34.         aa++;  
  35.     }  
  36.     return re;  
  37. }  

(2)equal函数

头文件

[cpp]  view plain  copy
  1. /************************* 
  2. *** File myEqual.h 
  3. **************************/  
  4. #ifndef MYEQUAL_H_INCLUDED  
  5. #define MYEQUAL_H_INCLUDED  
  6.   
  7. //默认的相等的方法  
  8. int myEqualDefault(void * a, void *b);  
  9.   
  10. //int类型相等的方法  
  11. int myEqualInt(void * a, void *b);  
  12.   
  13. //char类型相等的方法  
  14. int myEqualChar(void * a, void *b);  
  15.   
  16. //string类型相等的方法  
  17. int myEqualString(void * a, void *b);  
  18.   
  19. #endif // MYEQUAL_H_INCLUDED  

源文件

[cpp]  view plain  copy
  1. /************************* 
  2. *** File myEqual.c 
  3. **************************/  
  4. #include "myEqual.h"  
  5. #include   
  6.   
  7. //默认的相等的方法  
  8. int myEqualDefault(void * a, void *b)  
  9. {  
  10.     return a == b;  
  11. }  
  12.   
  13. //int类型相等的方法  
  14. int myEqualInt(void * a, void *b)  
  15. {  
  16.     int *aa = (int*) a;  
  17.     int *bb = (int *) b;  
  18.     return *aa == *bb;  
  19. }  
  20.   
  21. //char类型相等的方法  
  22. int myEqualChar(void * a, void *b)  
  23. {  
  24.     char *aa = (char *) a;  
  25.     char *bb = (char *) b;  
  26.     return *aa = *bb;  
  27. }  
  28.   
  29. //string类型相等的方法  
  30. int myEqualString(void * a, void *b)  
  31. {  
  32.     char *aa = (char *) a;  
  33.     char *bb = (char *) b;  
  34.     return strcmp(aa, bb)==0;  
  35. }  

(3)HashSet

头文件

[cpp]  view plain  copy
  1. #ifndef MYHASHSET_H_INCLUDED  
  2. #define MYHASHSET_H_INCLUDED  
  3.   
  4. # include "myHashMap.h"  
  5.   
  6. typedef struct myHashSet  
  7. {  
  8.     int size; //大小  
  9.     int initialCapacity; //初始容量  
  10.     float loadFactor; //加载因子  
  11.     int (*hashCode)(void *data);  
  12.     int (*equal)(void *data1, void *data2);  
  13.     MyList ** dataList;  
  14. } MyHashSet;  
  15.   
  16. typedef struct myHashSetIterator  
  17. {  
  18.     int index; //第几个链表  
  19.     MyHashSet *set;  
  20.     MyNode *current;  
  21.     int count; //第几个数据  
  22. } MyHashSetIterator;  
  23.   
  24. //创建HashSet  
  25. MyHashSet *createMyHashSet(int (*hashCode)(void *data),int (*equal)(void *data1,void *data2));  
  26.   
  27. //使用全部参数创建HashSet  
  28. MyHashSet *createMyHashSetForAll(int initialCapacity,float loadFactor,int (*hashCode)(void *data),int (*equal)(void *data1,void *data2));  
  29.   
  30. //释放HashSet  
  31. void freeMyHashSet(MyHashSet * set);  
  32.   
  33. //是否包含某个data  
  34. int myHashSetContains(MyHashSet * const set, void * const data);  
  35.   
  36. //增加一条数据,返回是否添加成功  
  37. int myHashSetAddData(MyHashSet * const set, void * const data);  
  38.   
  39. //数据的容量  
  40. int myHashSetGetSize(const MyHashSet * const set);  
  41.   
  42. //创建迭代器  
  43. MyHashSetIterator* createMyHashSetIterator(MyHashSet * const set);  
  44.   
  45. //释放迭代器  
  46. void freeMyHashSetIterator(MyHashSetIterator* iterator);  
  47.   
  48. //迭代器是否有下一个  
  49. int myHashSetIteratorHasNext(MyHashSetIterator* iterator);  
  50.   
  51. //遍历下一个元素  
  52. void* myHashSetIteratorNext(MyHashSetIterator* iterator);  
  53.   
  54. //删除一条数据,返回是否删除成功  
  55. int myHashSetRemoveData(MyHashSet * const set, void * const data);  
  56.   
  57. //将第二个Set的全部对象加入到第一个,返回增加的个数  
  58. int myHashSetAddAllSet(MyHashSet * set,MyHashSet *other);  
  59.   
  60. //复制HashSet  
  61. MyHashSet* myHashSetCopy(MyHashSet * set);  
  62.   
  63. //遍历  
  64. void myHashSetOutput(MyHashSet *set, void(*pt)(void*));  
  65.   
  66. #endif // MYHASHSET_H_INCLUDED  

源文件

[cpp]  view plain  copy
  1. # include "myHashSet.h"  
  2. #include   
  3. //创建HashSet  
  4. MyHashSet *createMyHashSet(int(*hashCode)(void *data), int(*equal)(void *data1, void *data2))  
  5. {  
  6.     MyHashSet *re = malloc(sizeof(MyHashSet));  
  7.     re->size = 0;  
  8.     re->loadFactor = DEFAULT_LOAD_FACTOR;  
  9.     re->initialCapacity = DEFAULT_INITIAL_CAPACITY;  
  10.     re->dataList = (MyList **) malloc(sizeof(MyList*) * re->initialCapacity);  
  11.     re->hashCode = hashCode;  
  12.     re->equal = equal;  
  13.     for (int i = 0; i < re->initialCapacity; i++)  
  14.     {  
  15.         re->dataList[i] = createMySearchList(equal);  
  16.     }  
  17.     return re;  
  18. }  
  19.   
  20. //使用全部参数创建HashSet  
  21. MyHashSet *createMyHashSetForAll(int initialCapacity, float loadFactor, int(*hashCode)(void *data), int(*equal)(void *data1, void *data2))  
  22. {  
  23.     MyHashSet *re = createMyHashSet(hashCode, equal);  
  24.     re->initialCapacity = initialCapacity;  
  25.     re->loadFactor = loadFactor;  
  26.     return re;  
  27. }  
  28.   
  29. //释放HashSet  
  30. void freeMyHashSet(MyHashSet * set)  
  31. {  
  32.     for (int i = 0; i < set->initialCapacity; i++)  
  33.     {  
  34.         freeMyList(set->dataList[i]);  
  35.     }  
  36.     free(set->dataList);  
  37.     free(set);  
  38. }  
  39.   
  40. //是否包含某个data  
  41. int myHashSetContains(MyHashSet * const set, void * const data)  
  42. {  
  43.     int hasCode = (*(set->hashCode))(data);  
  44.     hasCode %= set->initialCapacity;  
  45.     if (hasCode<0)  
  46.         hasCode+=set->initialCapacity;  
  47.     int re = myListFindDataIndex(set->dataList[hasCode], data);  
  48.     return re > -1;  
  49. }  
  50.   
  51. void rebuildMyHashSet(MyHashSet * set)  
  52. {  
  53.     int newSize = set->initialCapacity * 2;  
  54.     MyList **newdataList = (MyList **) malloc(sizeof(MyList*) * newSize);  
  55.     for (int i = 0; i < newSize; i++)  
  56.     {  
  57.         newdataList[i] = createMyList();  
  58.     }  
  59.     MyHashSetIterator* it = createMyHashSetIterator(set);  
  60.     while (myHashSetIteratorHasNext(it))  
  61.     {  
  62.         void * data = myHashSetIteratorNext(it);  
  63.         int hasCode = (*(set->hashCode))(data);  
  64.         hasCode %= newSize;  
  65.         myListInsertDataAtLast(newdataList[hasCode], data);  
  66.     }  
  67.     freeMyHashSetIterator(it);  
  68.     for (int i = 0; i < set->initialCapacity; i++)  
  69.     {  
  70.         freeMyList(set->dataList[i]);  
  71.     }  
  72.     free(set->dataList);  
  73.     set->dataList = newdataList;  
  74.     set->initialCapacity = newSize;  
  75. }  
  76.   
  77. //增加一条数据,返回是否添加成功  
  78. int myHashSetAddData(MyHashSet * const set, void * const data)  
  79. {  
  80.     int hasCode = (*(set->hashCode))(data);  
  81.     hasCode %= set->initialCapacity;  
  82.     if (hasCode<0)  
  83.         hasCode+=set->initialCapacity;  
  84.     int re = myListFindDataIndex(set->dataList[hasCode], data);  
  85.     if (re == -1)  
  86.     {  
  87.         myListInsertDataAtLast(set->dataList[hasCode], data);  
  88.         (set->size)++;  
  89.         if (set->size > set->initialCapacity * set->loadFactor)  
  90.         {  
  91.             rebuildMyHashSet(set);  
  92.         }  
  93.         return 1;  
  94.     }  
  95.     return 0;  
  96. }  
  97.   
  98. //数据的容量  
  99. int myHashSetGetSize(const MyHashSet * const set)  
  100. {  
  101.     return set->size;  
  102. }  
  103.   
  104. //创建迭代器  
  105. MyHashSetIterator* createMyHashSetIterator(MyHashSet * const set)  
  106. {  
  107.     MyHashSetIterator* re = (MyHashSetIterator*) malloc(  
  108.                                 sizeof(MyHashSetIterator));  
  109.     re->count = 0;  
  110.     re->index = 0;  
  111.     re->set = set;  
  112.     re->current = set->dataList[0]->first;  
  113.     return re;  
  114. }  
  115.   
  116. //释放迭代器  
  117. void freeMyHashSetIterator(MyHashSetIterator* iterator)  
  118. {  
  119.     free(iterator);  
  120. }  
  121.   
  122. //迭代器是否有下一个  
  123. int myHashSetIteratorHasNext(MyHashSetIterator* iterator)  
  124. {  
  125.     return iterator->count < iterator->set->size;  
  126. }  
  127.   
  128. //遍历下一个元素  
  129. void* myHashSetIteratorNext(MyHashSetIterator* iterator)  
  130. {  
  131.     (iterator->count)++;  
  132.     while (!(iterator->current))  
  133.     {  
  134.         (iterator->index)++;  
  135.         iterator->current = iterator->set->dataList[iterator->index]->first;  
  136.     }  
  137.     void * re = iterator->current->data;  
  138.     iterator->current = iterator->current->next;  
  139.     return re;  
  140. }  
  141.   
  142. //删除一条数据,返回是否删除成功  
  143. int myHashSetRemoveData(MyHashSet * const set, void * const data)  
  144. {  
  145.     int hasCode = (*(set->hashCode))(data);  
  146.     hasCode %= set->initialCapacity;  
  147.     if (hasCode<0)  
  148.         hasCode+=set->initialCapacity;  
  149.     int re = myListRemoveDataObject(set->dataList[hasCode], data);  
  150.     if (re)  
  151.     {  
  152.         (set->size)--;  
  153.     }  
  154.     return re;  
  155. }  
  156.   
  157. //将第二个Set的全部对象加入到第一个,返回增加的个数  
  158. int myHashSetAddAllSet(MyHashSet * set,MyHashSet *other)  
  159. {  
  160.     int ssize=set->size;  
  161.     MyHashSetIterator * it=createMyHashSetIterator(other);  
  162.     while (myHashSetIteratorHasNext(it))  
  163.     {  
  164.         myHashSetAddData(set,myHashSetIteratorNext(it));  
  165.     }  
  166.     freeMyHashSetIterator(it);  
  167.     int re=set->size-ssize;  
  168.     return re;  
  169. }  
  170.   
  171. //复制HashSet  
  172. MyHashSet* myHashSetCopy(MyHashSet * set)  
  173. {  
  174.     MyHashSet* re=createMyHashSetForAll(set->initialCapacity,set->loadFactor,set->hashCode,set->equal);  
  175.     myHashSetAddAllSet(re,set);  
  176.     return re;  
  177. }  
  178.   
  179. //遍历  
  180. void myHashSetOutput(MyHashSet *set, void(*pt)(void*))  
  181. {  
  182.     MyHashSetIterator * it=createMyHashSetIterator(set);  
  183.     while (myHashSetIteratorHasNext(it))  
  184.     {  
  185.         pt(myHashSetIteratorNext(it));  
  186.     }  
  187.     freeMyHashSetIterator(it);  
  188. }  

(4)测试文件

[cpp]  view plain  copy
  1. /************************* 
  2. *** File main.c 
  3. *** test for MyHashSet 
  4. **************************/  
  5. #include   
  6. #include   
  7. #include "myEqual.h"  
  8. #include "myHashCode.h"  
  9. #include "myHashSet.h"  
  10.   
  11. #define S 10  
  12.   
  13. char* strs[S]=  
  14. {  
  15.     "abc",  
  16.     "qq",  
  17.     "hello",  
  18.     "abc",  
  19.     "lmy",  
  20.     "ab",  
  21.     "qq",  
  22.     "lqw",  
  23.     "sww",  
  24.     "lqw"  
  25. };  
  26.   
  27.   
  28. int main()  
  29. {  
  30.     //创建集合需要指定两个函数,hashCode函数和equal函数。  
  31.     MyHashSet * set = createMyHashSet(myHashCodeString, myEqualString);  
  32.   
  33.     //插入数据  
  34.     for (int i=0; i
  35.     {  
  36.         myHashSetAddData(set, strs[i]);  
  37.     }  
  38.   
  39.     //输出大小  
  40.     printf("size=%d\n",myHashSetGetSize(set));  
  41.   
  42.     //测试删除  
  43.     myHashSetRemoveData(set,"qq");  
  44.     myHashSetRemoveData(set,"ab");  
  45.     myHashSetRemoveData(set,"qwert");  
  46.   
  47.     //输出大小  
  48.     printf("after remove size=%d\n",myHashSetGetSize(set));  
  49.   
  50.     //遍历  
  51.     MyHashSetIterator * it = createMyHashSetIterator(set);  
  52.     while(myHashSetIteratorHasNext(it))  
  53.     {  
  54.         char * pp= myHashSetIteratorNext(it);  
  55.         puts(pp);  
  56.     }  
  57.     //释放遍历器  
  58.     freeMyHashSetIterator(it);  
  59.   
  60.     //释放集合  
  61.     freeMyHashSet(set);  
  62.     return 0;  
  63. }  



你可能感兴趣的:(c/c++编程)