Hash

书上的代码 整理一下

  1  /*
  2  * Copyright (c) 2000-2008
  3  * Author: Weiming Zhou
  4  *
  5  * Permission to use, copy, modify, distribute and sell this software
  6  * and its documentation for any purpose is hereby granted without fee,
  7  * provided that the above copyright notice appear in all copies and
  8  * that both that copyright notice and this permission notice appear
  9  * in supporting documentation.  
 10  */
 11 
 12 #ifndef __HASHLIST_H__
 13 #define __HASHLIST_H__
 14 
 15 #ifdef __cplusplus
 16 extern "C" {
 17 #endif
 18 
 19 #define MINIUM_BUCKET_COUNT   32
 20 
 21 
 22 typedef struct HASHLISTNODE_st {
 23     struct HASHLISTNODE_st *pListNext;   /* 链表的后向节点指针 */
 24     struct HASHLISTNODE_st *pListPrev;   /* 链表的前向节点指针 */
 25     struct HASHLISTNODE_st *pBucketNext; /* 哈希表的链接指针 */
 26     void             *pData;             /* 数据指针 */
 27 } HASHLISTNODE;
 28 
 29 typedef struct HASHLIST_st {
 30     HASHLISTNODE **ppBuckets;    /* 哈希表的索引表 */
 31     UINT         uBucketCount;   /* 索引表的大小 */
 32     HASHLISTNODE *pHead;         /* 链表的头指针 */
 33     HASHLISTNODE *pTail;         /* 链表的尾指针 */
 34     UINT         uNodeCount;     /* 哈希链表中的节点个数 */
 35 } HASHLIST;
 36 
 37 
 38 HASHLIST *HashList_Create(UINT uBucketCount);
 39 
 40 void HashList_Destroy(HASHLIST *pHashList, 
 41                        DESTROYFUNC DestroyFunc);
 42 
 43 INT HashList_InsertHead(HASHLIST *pHashList, void *pData, HASHFUNC HashFunc);
 44 
 45 INT HashList_Delete(HASHLIST *pHashList, 
 46                     void           *pData,
 47                     HASHFUNC        HashFunc,
 48                     COMPAREFUNC     HashCompareFunc, 
 49                     DESTROYFUNC     DestroyFunc);
 50 
 51 
 52 HASHLISTNODE *HashList_FindNode(HASHLIST *pHashList, 
 53                                 void *pData, 
 54                                 HASHFUNC HashFunc, 
 55                                 COMPAREFUNC CompareFunc);
 56 
 57 void *HashList_FindData(HASHLIST *pHashList, 
 58                         void *pData, 
 59                         HASHFUNC HashFunc, 
 60                         COMPAREFUNC CompareFunc);
 61 
 62 INT HashList_InsertSort(HASHLIST *pHashList, COMPAREFUNC CompareFunc);
 63 
 64 
 65 UINT        HashStr( void *str, UINT str_len, UINT numBuckets );
 66 UINT        HashStrCompare( void *str1, UINT str1_len, void *str2, UINT str2_len );
 67 void        HashFree(void *pData, UINT uDataLen);
 68 
 69 #ifdef __cplusplus
 70 }
 71 #endif
 72 
 73 #endif /* __HASHLIST_H__ */
 74 
 75 
 76 /*
 77  * Copyright (c) 2000-2008
 78  * Author: Weiming Zhou
 79  *
 80  * Permission to use, copy, modify, distribute and sell this software
 81  * and its documentation for any purpose is hereby granted without fee,
 82  * provided that the above copyright notice appear in all copies and
 83  * that both that copyright notice and this permission notice appear
 84  * in supporting documentation.  
 85  */
 86 
 87 #include <stdlib.h>
 88 #include "CapiGlobal.h"
 89 #include "HashList.h"
 90 
 91 
 92 /**    哈希链表的创建函数
 93 
 94     @param    UINT uBucketCount - 索引表的大小    
 95     @return    HASHLIST * - 成功返回哈希表的指针,失败返回NULL    
 96 */
 97 HASHLIST *HashList_Create(UINT uBucketCount)
 98 {
 99     HASHLIST    *pHashList;
100 
101     /* 假设uBucketCount最小值不能低于MINIUM_BUCKET_COUNT */
102     if ( uBucketCount < MINIUM_BUCKET_COUNT )
103     {
104         uBucketCount = MINIUM_BUCKET_COUNT;
105     }
106 
107     pHashList = (HASHLIST *)malloc(sizeof(HASHLIST));
108     if ( pHashList != NULL)
109     {
110         /* 创建哈希链表里的哈希表的索引表并初始化哈希表 */
111         pHashList->ppBuckets = (HASHLISTNODE **)malloc(uBucketCount 
112             * sizeof(HASHLISTNODE *));
113         if ( pHashList->ppBuckets == NULL )
114         {
115             free(pHashList);
116             return NULL;
117         }
118         memset((void *)pHashList->ppBuckets, 0, 
119             uBucketCount * sizeof(HASHLISTNODE *));
120 
121         /* 初始化哈希表里面的双向链表 */
122         pHashList->pHead = NULL;
123         pHashList->pTail = NULL;
124         pHashList->uBucketCount = uBucketCount;
125         pHashList->uNodeCount = 0;
126     }
127 
128     return pHashList;
129 }
130 
131 
132 /**    哈希链表的释放函数
133 
134     @param    HASHLIST *pHashList - 哈希链表指针    
135     @param  DESTROYFUNC DestroyFunc - 数据释放回调函数    
136     @return    void - 无    
137 */
138 void HashList_Destroy(HASHLIST *pHashList, 
139                       DESTROYFUNC DestroyFunc )
140 {
141     UINT uIndex;
142     if ( pHashList == NULL )
143     {
144         return;
145     }
146 
147     for ( uIndex = 0; uIndex < pHashList->uBucketCount; uIndex++ )
148     {
149         HASHLISTNODE    *pNode;
150         pNode = pHashList->ppBuckets[uIndex];
151         while ( pNode != NULL )
152         {
153             HASHLISTNODE *pNodeToFree;
154 
155             pNodeToFree = pNode;
156             pNode = pNode->pBucketNext;
157             if ( DestroyFunc != NULL && pNodeToFree->pData != NULL )
158             {
159                 (*DestroyFunc)(pNodeToFree->pData);
160             }
161 
162             free(pNodeToFree);
163         }
164     }
165 
166     free(pHashList->ppBuckets);
167     free(pHashList);
168 
169     return;
170 }
171 
172 
173 /**    哈希链表的数据插入函数,同时插入到哈希表和链表中,
174     插入链表时是插入在链表的头部
175 
176     @param    HASHLIST *pHashList - 哈希链表指针    
177     @param    void *pData - 要插入的数据指针    
178     @param    HASHFUNC HashFunc - 哈希函数    
179     @return    INT - CAPI_FAILED表示失败,CAPI_SUCCESS表示成功    
180 */
181 INT HashList_InsertHead(HASHLIST *pHashList, void *pData, HASHFUNC HashFunc)
182 {
183     HASHLISTNODE    *pNode;
184     UINT            uBucketIndex;
185 
186     if ( pHashList == NULL || pData == NULL )
187     {
188         return CAPI_FAILED;
189     }
190 
191     /* 生成哈希链表的节点 */
192     pNode = (HASHLISTNODE *)malloc(sizeof(HASHLISTNODE));
193     if ( pNode == NULL )
194     {
195         return CAPI_FAILED;
196     }
197     pNode->pData = pData;
198     pNode->pBucketNext = NULL;
199     pNode->pListPrev = NULL;
200     pNode->pListNext = pHashList->pHead;
201 
202     /* 插入到哈希表中 */
203     uBucketIndex = (*HashFunc)(pData, pHashList->uBucketCount);
204 
205     if ( pHashList->ppBuckets[uBucketIndex] == NULL )
206     {
207         pHashList->ppBuckets[uBucketIndex] = pNode;
208     }
209     else
210     {
211         HASHLISTNODE    *pTempNode;
212         pTempNode = pHashList->ppBuckets[uBucketIndex];
213         while ( pTempNode->pBucketNext != NULL )
214         {
215             pTempNode = pTempNode->pBucketNext;
216         }
217         pTempNode->pBucketNext = pNode;
218     }
219 
220     /* 插入到链表中 */
221     if ( pHashList->pHead == NULL )
222     {
223         pHashList->pHead = pNode;
224         pHashList->pTail = pNode;
225     }
226     else
227     {
228         pNode->pListNext = pHashList->pHead;
229         pHashList->pHead->pListPrev = pNode;
230         pHashList->pHead = pNode;
231     }
232 
233     pHashList->uNodeCount += 1;
234 
235     return CAPI_SUCCESS;
236 }
237 
238 
239 /**    哈希链表的单个节点删除函数,要同时从哈希表和链表中删除
240 
241     @param    HASHLIST *pHashList - 哈希链表指针    
242     @param  void           *pData - 数据指针    
243     @param  HASHFUNC        HashFunc - 哈希函数    
244     @param  COMPAREFUNC     CompareFunc - 数据比较函数    
245     @param  DESTROYFUNC     DestroyFunc - 数据释放函数    
246     @return    INT - CAPI_FAILED表示失败,CAPI_SUCCESS表示成功        
247 */
248 INT HashList_Delete(HASHLIST *pHashList, 
249                     void           *pData,
250                     HASHFUNC        HashFunc,
251                     COMPAREFUNC     CompareFunc, 
252                     DESTROYFUNC     DestroyFunc)
253 {
254     HASHLISTNODE    *pNode;
255     HASHLISTNODE    *pPrevNode;
256     UINT            uIndex;
257 
258     if ( pHashList == NULL || HashFunc == NULL 
259         || CompareFunc == NULL )
260     {
261         return CAPI_FAILED;
262     }
263 
264     uIndex = (*HashFunc)(pData, pHashList->uBucketCount);
265     pNode = pHashList->ppBuckets[uIndex];
266     pPrevNode = NULL;
267 
268     while ( pNode != NULL )
269     {
270         if ( (*CompareFunc)(pNode->pData, pData ) == 0 )
271         {
272             if (pPrevNode == NULL )
273             {
274                 pHashList->ppBuckets[uIndex] = pNode->pBucketNext;
275             }
276             else
277             {
278                 pPrevNode->pBucketNext = pNode->pBucketNext;
279             }
280 
281             /* 从链表中删除节点 */
282             if ( pNode->pListPrev != NULL )
283             {
284                 pNode->pListPrev->pListNext = pNode->pListNext;
285             }
286             else
287             {
288                 /* pNode 是链表头指针 */
289                 pHashList->pHead = pNode->pListNext;
290             }
291 
292             if ( pNode->pListNext != NULL )
293             {
294                 pNode->pListNext->pListPrev = pNode->pListPrev;
295             }
296             else
297             {
298                 /* 现在在链表尾部 */
299                 pHashList->pTail = pNode;
300             }
301 
302             if ( pNode->pData != NULL && DestroyFunc != NULL )
303             {
304                 (*DestroyFunc)(pNode->pData);
305             }
306 
307             free(pNode);
308 
309             pHashList->uNodeCount -= 1;
310 
311             return CAPI_SUCCESS;
312         }
313         pPrevNode = pNode;
314         pNode = pNode->pBucketNext;
315     }
316 
317     return CAPI_FAILED;
318 }
319 
320 
321 /**    哈希链表的查找节点函数
322 
323     @param    HASHLIST *pHashList - 哈希链表指针    
324     @param    void *pData - 要查找的数据指针    
325     @param    HASHFUNC HashFunc - 哈希函数    
326     @param    COMPAREFUNC CompareFunc - 数据比较函数    
327     @return    HASHLISTNODE * - 成功返回查找到的哈希链表节点指针,
328                              失败返回NULL    
329 */
330 HASHLISTNODE *HashList_FindNode(HASHLIST *pHashList, 
331                                 void *pData, 
332                                 HASHFUNC HashFunc, 
333                                 COMPAREFUNC CompareFunc)
334 {
335     HASHLISTNODE    *pNode;
336     UINT            uIndex;
337 
338     if ( pHashList == NULL || HashFunc == NULL 
339         || CompareFunc == NULL )
340     {
341         return NULL;
342     }
343 
344     uIndex = (*HashFunc)(pData, pHashList->uBucketCount);
345     pNode = pHashList->ppBuckets[uIndex];
346 
347     /* try to find the key from the HashTable */
348     while ( pNode != NULL )
349     {
350         if ( (*CompareFunc)(pNode->pData, pData) == 0 )
351         {
352             /* 发现匹配的节点,返回节点指针 */
353             return pNode;
354         }
355         pNode = pNode->pBucketNext;
356     }
357 
358     /* 没有找到的情况下,返回NULL */
359     return NULL;
360 }
361 
362  
363 /**    哈希链表的查找数据函数
364 
365     @param    HASHLIST *pHashList - 哈希链表指针    
366     @param    void *pData - 要查找的数据指针    
367     @param    HASHFUNC HashFunc - 哈希函数    
368     @param    COMPAREFUNC CompareFunc - 数据比较函数    
369     @return    void * - 成功返回查找到的数据指针,失败返回NULL    
370 */
371 void *HashList_FindData(HASHLIST *pHashList, 
372                         void *pData, 
373                         HASHFUNC HashFunc, 
374                         COMPAREFUNC CompareFunc)
375 {
376     HASHLISTNODE    *pNode;
377     UINT            uIndex;
378 
379     if ( pHashList == NULL || HashFunc == NULL 
380         || CompareFunc == NULL )
381     {
382         return NULL;
383     }
384 
385     uIndex = (*HashFunc)(pData, pHashList->uBucketCount);
386     pNode = pHashList->ppBuckets[uIndex];
387 
388     /* try to find the key from the HashTable */
389     while ( pNode != NULL )
390     {
391         if ( (*CompareFunc)(pNode->pData, pData) == 0 )
392         {
393             /* 发现匹配的节点,返回节点指针 */
394             return pNode->pData;
395         }
396         pNode = pNode->pBucketNext;
397     }
398 
399     /* 没有找到的情况下,返回NULL */
400     return NULL;
401 }
402 
403 
404 /**    哈希链表的插入排序函数,用插入排序算法对哈希链表里的链表进行排序
405 
406     @param    HASHLIST *pHashList - 哈希链表指针    
407     @param    COMPAREFUNC CompareFunc - 数据比较函数    
408     @return    INT - CAPI_FAILED表示失败,CAPI_SUCCESS表示成功     
409 */
410 INT HashList_InsertSort(HASHLIST *pHashList, COMPAREFUNC CompareFunc)
411 {
412     HASHLISTNODE    *pNode;
413 
414     if ( pHashList == NULL || CompareFunc == NULL )
415     {
416         return 0;
417     }
418 
419     pNode = pHashList->pHead;
420     if ( pNode == NULL )
421     {
422         /* 没有节点在链表中,把它当作已经排好了序 */
423         return 1;
424     }
425 
426     while ( pNode->pListNext != NULL )
427     {
428         if ( (*CompareFunc)( pNode->pListNext->pData, pNode->pData ) < 0 )
429         {
430             HASHLISTNODE    *pTempNode;
431             pTempNode = pNode->pListPrev;
432             while ( pTempNode != NULL )
433             {
434                 if ( (*CompareFunc)( pNode->pListNext->pData, 
435                     pTempNode->pData ) >= 0 )
436                 {
437                     HASHLISTNODE    *pCurNode;
438 
439                     /* 将节点弹出来 */
440                     pCurNode = pNode->pListNext;
441                     pNode->pListNext = pNode->pListNext->pListNext;
442                     if ( pCurNode->pListNext != NULL )
443                     {
444                         pCurNode->pListNext->pListPrev = pNode;
445                     }
446 
447                     /* 将节点插入到对应位置上 */
448                     pCurNode->pListNext = pTempNode->pListNext;
449                     pCurNode->pListPrev = pTempNode;
450                     pTempNode->pListNext->pListPrev = pCurNode;
451                     pTempNode->pListNext = pCurNode;
452                     
453                     break;
454                 }
455                 pTempNode = pTempNode->pListPrev;
456             }
457 
458             /* 如果所有数据都大于该节点数据,将该节点插入到链表头部 */
459             if ( pTempNode == NULL )
460             {
461                 HASHLISTNODE    *pCurNode;
462 
463                 /* 将节点弹出来 */
464                 pCurNode = pNode->pListNext;
465                 pNode->pListNext = pNode->pListNext->pListNext;
466                 if ( pCurNode->pListNext != NULL )
467                 {
468                     pCurNode->pListNext->pListPrev = pNode;
469                 }
470 
471                 /* 将节点插入链表头部 */
472                 pCurNode->pListPrev = NULL;
473                 pCurNode->pListNext = pHashList->pHead;
474                 pHashList->pHead = pCurNode;
475             }
476         }
477         else
478         {
479             pNode = pNode->pListNext;
480         }
481     }
482 
483     return 1;
484 }
485 
486 
487 
488 /*
489  *    HashString( void *str )
490  *    Calculate the hash value of a string.
491  *    Parameters:
492  *        void *str,        the string that need calculate.
493  *    Return Values:
494  *        the hash value of the string.
495  */
496 UINT HashStr( void *str, UINT str_len, UINT numBuckets )
497 {
498     char    *s;
499 //    int        i;
500     int        hashval;
501     int        ret;
502     int        j;
503 
504 //    strupr( (char *)str );
505     s = (char *)str;
506     hashval = 0;
507 
508 #if 0
509     for ( i = 0; i < 5 && s[i] != '\0'; i++ )
510     {
511         hashval += hashval << 3;
512         hashval += s[i] ;
513     }
514 #endif
515     j = 0;
516     ret = 0;
517     while ( *s != '\0' )
518     {
519         if ( j == 5 )
520         {
521             j = 0;
522             ret += hashval;
523             hashval = 0;
524         }
525         hashval += hashval << 3;
526 //        hashval += tolower( (unsigned char)*s );
527         s++;
528         j++;
529     }
530     ret += hashval;
531 
532     return ret % numBuckets;
533 }
534 
535 /*
536  *    StrCompare( )
537  *    Compare if two string is equal.
538  *    Return Values:
539  *        1        equal
540  *        0        not equal
541  */
542 UINT HashStrCompare( void *str1, UINT str1_len, void *str2, UINT str2_len )
543 {
544     return stricmp( (char *)str1, (char *)str2 );
545 }
546 
547 void HashFree(void *pData, UINT uDataLen)
548 {
549     free( pData );
550 }
HashList
  1  /*
  2  * Copyright (c) 2000-2008
  3  * Author: Weiming Zhou
  4  *
  5  * Permission to use, copy, modify, distribute and sell this software
  6  * and its documentation for any purpose is hereby granted without fee,
  7  * provided that the above copyright notice appear in all copies and
  8  * that both that copyright notice and this permission notice appear
  9  * in supporting documentation.  
 10  */
 11 
 12 #ifndef __HASHTABLE_H__
 13 #define __HASHTABLE_H__
 14 
 15 #ifdef __cplusplus
 16 extern "C" {
 17 #endif
 18 
 19 #define        HASHTABLE_SIZE        32767
 20 #define        MAX_SEARCH_DEEP        30
 21 
 22 
 23 
 24 typedef struct HASHTABLE {
 25     SINGLENODE **ppBucket;        /* 索引表指针 */
 26     UINT         uBucketCount;    /* 索引表的大小. */
 27     UINT         uNodeCount;        /* 表中的实际节点个数. */
 28 
 29     UINT        uCurBucketNo;   /* 当前要执行的Bucket序号 */
 30     SINGLENODE *pCurEntry;      /* 当前bucket中的下一个要执行的节点条目 */ 
 31 } HASHTABLE;
 32 
 33 
 34 
 35 /*** Hash Table operation functions ***/
 36 HASHTABLE * HashTable_Create(UINT uBucketCount);
 37 
 38 void    HashTable_Destroy(HASHTABLE *pTable, 
 39                           DESTROYFUNC DestroyFunc );
 40 
 41 INT     HashTable_Insert( HASHTABLE *pTable, 
 42                           void *pData, 
 43                           HASHFUNC HashFunc);
 44 
 45 void *  HashTable_Find(HASHTABLE *pTable, 
 46                        void *pData, 
 47                        HASHFUNC HashFunc,
 48                        COMPAREFUNC CompareFunc);
 49 
 50 INT     HashTable_Delete(HASHTABLE *pTable, 
 51                          void *pData, 
 52                          HASHFUNC HashFunc,
 53                          COMPAREFUNC CompareFunc,
 54                          DESTROYFUNC DataDestroyFunc );
 55 
 56 void    HashTable_EnumBegin(HASHTABLE *pTable);
 57 void *  HashTable_EnumNext(HASHTABLE *pTable);
 58 
 59 
 60 
 61 
 62 #ifdef __cplusplus
 63 }
 64 #endif
 65 
 66 #endif /* __HASHTABLE_H__ */
 67 
 68 
 69 /*
 70  * Copyright (c) 2000-2008
 71  * Author: Weiming Zhou
 72  *
 73  * Permission to use, copy, modify, distribute and sell this software
 74  * and its documentation for any purpose is hereby granted without fee,
 75  * provided that the above copyright notice appear in all copies and
 76  * that both that copyright notice and this permission notice appear
 77  * in supporting documentation.  
 78  */
 79 
 80 #include <stdlib.h>
 81 #include <string.h>
 82 #include "CapiGlobal.h"
 83 #include "HashTable.h"
 84 
 85 
 86 /**    哈希表的创建函数
 87 
 88     @param    UINT uBucketCount - 索引的大小    
 89     @return    HASHTABLE * - 成功返回哈希表的指针,失败返回NULL    
 90 */
 91 HASHTABLE *    HashTable_Create(UINT uBucketCount)
 92 {
 93     HASHTABLE    *pTable;
 94 
 95     if ( uBucketCount == 0 )
 96     {
 97         return NULL;
 98     }
 99     
100     pTable = (HASHTABLE *)malloc( sizeof(HASHTABLE) );
101     if ( pTable == NULL )
102     {
103         return NULL;
104     }
105 
106     pTable->uNodeCount = 0;
107     pTable->uBucketCount = uBucketCount;
108 
109     pTable->ppBucket = (SINGLENODE **)malloc( uBucketCount 
110         * sizeof(SINGLENODE *));
111 
112     if (pTable->ppBucket == NULL)
113     {
114         free( pTable );
115         return NULL;
116     }
117 
118     memset(pTable->ppBucket, 0, uBucketCount * sizeof(SINGLENODE *));
119 
120     pTable->pCurEntry = NULL;
121     pTable->uCurBucketNo = 0;
122 
123     return pTable;
124 }
125 
126 
127 /**    哈希表的释放函数
128 
129     @param    HASHTABLE *pTable - 哈希表指针    
130     @param    DESTROYFUNC DestroyFunc - 数据释放函数,为NULL时只释放节点辅助
131                                       空间,不释放数据    
132     @return    void - 无    
133 */
134 void HashTable_Destroy( HASHTABLE *pTable, 
135                         DESTROYFUNC DestroyFunc)
136 {
137     SINGLENODE **ppBucket;
138     SINGLENODE  *pNode;
139     SINGLENODE  *pFreeNode;
140     UINT i;
141 
142 
143     if ( pTable == NULL )
144     {
145         return;
146     }
147     ppBucket = pTable->ppBucket;
148     for ( i = 0; i < pTable->uBucketCount; i++ ) 
149     {
150         pNode = ppBucket[i];
151         while ( pNode != NULL )
152         {
153             if ( DestroyFunc != NULL )
154             {
155                 (*DestroyFunc)(pNode->pData);
156             }
157             pFreeNode = pNode;
158             pNode = pNode->pNext;
159             free(pFreeNode);
160         }
161     }
162     free(ppBucket);
163 
164     /* 将ppbucket设成空指针以避免哈希表被重新使用时造成内存泄漏 */
165     pTable->ppBucket = NULL;
166 
167     free( pTable );
168 }
169 
170 
171 /**    哈希表的插入函数
172 
173     @param    HASHTABLE *pTable - 哈希表指针    
174     @param    void *pData - 数据指针,其中包含关键词信息    
175     @param    ASHFUNC HashFunc - 哈希函数,用来计算关键词的索引    
176     @return    INT (by default) - CAPI_SUCCESS表示成功,CAPI_FAILED表示失败    
177 */
178 INT    HashTable_Insert( HASHTABLE *pTable, 
179                     void *pData, 
180                     HASHFUNC HashFunc )
181 {
182     UINT        uIndex;
183     SINGLENODE    *pNode;
184     SINGLENODE    *pNewNode;
185 
186     if ( pTable == NULL || pData == NULL || HashFunc == NULL )
187     {
188         return CAPI_FAILED;
189     }
190 
191     uIndex = (*HashFunc)( pData, pTable->uBucketCount );
192     pNode = (pTable->ppBucket)[uIndex];
193 
194     pNewNode = (SINGLENODE *)malloc( sizeof(SINGLENODE) );
195 
196     if ( pNewNode == NULL )
197     {
198     return CAPI_FAILED;
199     }
200     
201     /* 将新节点插入到链表的头部 */
202     pNewNode->pData = pData;
203     pNewNode->pNext = pNode;
204 
205     (pTable->ppBucket)[uIndex] = pNewNode;
206     pTable->uNodeCount += 1;
207 
208     return CAPI_SUCCESS;
209 }
210 
211 
212 /**    哈希表的查找函数
213 
214     @param    HASHTABLE *pTable - 哈希表指针    
215     @param  void *pData - 包含关键词信息的数据指针    
216     @param  HASHFUNC HashFunc - 哈希表的计算索引函数    
217     @param  COMPAREFUNC CompareFunc - 关键词比较函数    
218     @return    void * - 查到的数据指针,未查到返回NULL    
219 */
220 void *    HashTable_Find(HASHTABLE *pTable, 
221                                void *pData, 
222                                HASHFUNC HashFunc,
223                                COMPAREFUNC CompareFunc)
224 {
225     UINT            uIndex;
226     SINGLENODE *    pNode;
227 
228     if ( pTable == NULL || HashFunc == NULL || CompareFunc == NULL )
229     {
230         return NULL;
231     }
232 
233     uIndex = (*HashFunc)( pData, pTable->uBucketCount );
234     pNode = (pTable->ppBucket)[uIndex];
235     
236     /* 在 HASHTABLE 中进行查找 */
237     while ( pNode != NULL )
238     {
239         if ( (*CompareFunc)( pNode->pData, pData) == 0 )
240         {
241             /* 已经找到了关键词,返回 */
242             return pNode->pData;
243         }
244         pNode = pNode->pNext;
245     }
246 
247     return NULL;
248 }
249 
250 
251 /**    哈希表的删除函数
252 
253     @param    HASHTABLE *pTable - 哈西表指针    
254     @param  void *pData - 包含关键词信息的数据指针    
255     @param  HASHFUNC HashFunc - 哈希函数,用来计算关键词的索引    
256     @param  COMPAREFUNC CompareFunc - 关键词比较函数    
257     @param  DESTROYFUNC DataDestroyFunc - 数据释放函数    
258     @return    INT - CAPI_FAILED表示失败,CAPI_SUCCESS表示成功    
259 */
260 INT HashTable_Delete(HASHTABLE *pTable, 
261                      void *pData, 
262                      HASHFUNC HashFunc,
263                      COMPAREFUNC CompareFunc,
264                      DESTROYFUNC DataDestroyFunc )
265 
266 {
267     UINT            uIndex;
268     SINGLENODE *    pNode;
269     SINGLENODE *    pPrevNode;
270 
271     if ( pTable == NULL || pData == NULL || HashFunc == NULL 
272         || CompareFunc == NULL )
273     {
274         return CAPI_FAILED;
275     }
276 
277     uIndex = (*HashFunc)( pData, pTable->uBucketCount );
278     pNode = (pTable->ppBucket)[uIndex];
279     pPrevNode = pNode;
280 
281     /* 从哈希表中查找 */
282     while ( pNode != NULL )
283     {
284         if ( (*CompareFunc)( pNode->pData, pData ) == 0 )
285         {
286             if ( pPrevNode == pNode )
287             {
288                 pTable->ppBucket[uIndex] = pNode->pNext;
289             }
290             else
291             {
292                 pPrevNode->pNext = pNode->pNext;
293             }
294 
295             /* 删除对应节点 */
296             if ( DataDestroyFunc != NULL )
297             {
298                 (*DataDestroyFunc)(pNode->pData);
299             }
300             free(pNode);
301 
302             pTable->uNodeCount -= 1;
303 
304             return 1;
305         }
306 
307         pPrevNode = pNode;
308         pNode = pNode->pNext;
309     }
310 
311     return 0;
312 }
313 
314 
315 /**    哈希表的逐个节点遍历初始化函数
316 
317     @param    HASHTABLE *pTable - 哈希表指针    
318     @return    void - 无    
319 */
320 void HashTable_EnumBegin(HASHTABLE *pTable)
321 {
322     pTable->uCurBucketNo = 0;
323     pTable->pCurEntry = pTable->ppBucket[0];
324 }
325 
326 
327 /**    哈希表的逐个节点遍历函数
328 
329     @param    HASHTABLE *pTable - 哈希表指针    
330     @return    void * - 遍历到的节点的数据指针    
331 */
332 void * HashTable_EnumNext(HASHTABLE *pTable)
333 {
334     void *pData;
335 
336     while ( pTable->pCurEntry == NULL )
337     {
338         pTable->uCurBucketNo += 1;
339         if ( pTable->uCurBucketNo >= pTable->uBucketCount )
340         {
341             return NULL;
342         }
343         pTable->pCurEntry = pTable->ppBucket[pTable->uCurBucketNo];
344     }
345 
346     pData = pTable->pCurEntry->pData;
347 
348     pTable->pCurEntry = pTable->pCurEntry->pNext;
349 
350     return pData;
351 }
352 
353 
354 /**    哈希表的计算整数的索引函数
355 
356     @param    UINT uKey - 关键词    
357     @param    UINT uBucketCount - 哈希表的大小,用来做整除的模    
358     @return    UINT - 索引值    
359 */
360 UINT HashInt( void *pKey, UINT uBucketCount )
361 {
362     return ((UINT)pKey) % uBucketCount;
363 }
364 
365 
366 /**    字符串类型数据的关键词索引计算函数
367     将字符串折叠成每5个字符一段,每段看成是8进制整数,将各段相加后再取余数
368 
369     @param    void *pStr - 字符串指针    
370     @param    UINT uBucketCount - 最大桶的个数,实际上被用来做为整除的模    
371     @return    UINT - 字符串关键词的索引    
372 */
373 UINT HashString( void *pStr, UINT uBucketCount )
374 {
375     unsigned char    *psz;
376     UINT    uHashValue;
377     UINT    uRet;
378     UINT    i;
379 
380     psz = (unsigned char *)pStr;
381     uHashValue = 0;
382 
383     i = 0;
384     uRet = 0;
385     while ( *psz != '\0' )
386     {
387         if ( i == 5 )
388         {
389             i = 0;
390             uRet += uHashValue;
391             uHashValue = 0;
392         }
393         uHashValue += uHashValue << 3;
394         uHashValue += (UINT)tolower( *psz );
395         psz++;
396         i++;
397     }
398 
399     uRet += uHashValue;
400 
401     return uRet % uBucketCount;
402 }
403 
404 
405 /*
406  *    HashBin( void *str )
407  *    Calculate the hash value of a string.
408  *    Parameters:
409  *        void *str,        the string that need calculate.
410  *    Return Values:
411  *        the hash value of the string.
412  */
413 UINT HashBin( void *pData, UINT uLength, UINT uBucketCount )
414 {
415     unsigned char    *psz;
416     UINT    uHashValue;
417     UINT    uRet;
418     UINT    i;
419     UINT    j;
420 
421     psz = (unsigned char *)pData;
422     uHashValue = 0;
423 
424 
425     j = 0;
426     uRet = 0;
427     i = 0;
428     while ( i < uLength )
429     {
430         if ( j == 5 )
431         {
432             j = 0;
433             uRet += uHashValue;
434             uHashValue = 0;
435         }
436         uHashValue += uHashValue << 3;
437         uHashValue += (UINT)tolower( *psz );
438         psz++;
439         j++;
440         i++;
441     }
442 
443     uRet += uHashValue;
444 
445     return uRet % uBucketCount;
446 }
447 
448 
449 /*
450  *    BinCompare( )
451  *    Compare if two binary data is equal.
452  *    Return Values:
453  *        1        equal
454  *        0        not equal
455  */
456 UINT                
457 BinCompare( void *str1, int str1_len, void *str2, int str2_len )
458 {
459     char    *psz1, *psz2;
460     int        i;
461 
462     if ( str1_len != str2_len )
463     {
464         return 0;
465     }
466 
467     psz1 = (char *)str1;
468     psz2 = (char *)str2;
469 
470     i = 0;
471     while ( i < str1_len )
472     {
473         if ( *psz1 != *psz2 )
474         {
475             return 0;
476         }
477         psz1++;
478         psz2++;
479         i++;
480     }
481 
482     return 1;
483 }
484 
485 
486 /*
487  *    StrCompare( )
488  *    Compare if two string is equal.
489  *    Return Values:
490  *        1        pStr1 greater than pStr2
491  *        0        pStr1 equal to pStr2
492  *      -1      pStr1 less than pStr2
493  */
494 INT StrCompare( void *pStr1, void *pStr2 )
495 {
496     return stricmp( (char *)pStr1, (char *)pStr2 );
497 }
HashTable
  1  /*
  2  * Copyright (c) 2000-2008
  3  * Author: Weiming Zhou
  4  *
  5  * Permission to use, copy, modify, distribute and sell this software
  6  * and its documentation for any purpose is hereby granted without fee,
  7  * provided that the above copyright notice appear in all copies and
  8  * that both that copyright notice and this permission notice appear
  9  * in supporting documentation.  
 10  */
 11 
 12 #ifndef __HASHRBTREE_H__
 13 #define __HASHRBTREE_H__
 14 
 15 
 16 #ifdef __cplusplus
 17 extern "C" {
 18 #endif
 19 
 20 #if 0
 21 typedef struct HASHRBTREENODE_st {
 22     struct HASHRBTREENODE_st *pLeft;
 23     struct HASHRBTREENODE_st *pRight;
 24     struct HASHRBTREENODE_st *pParent;
 25     INT                      nColor;
 26     
 27     struct HASHRBTREENODE_st *pNext;
 28 
 29     void    *pKey;
 30     UINT    ukeyLen;
 31     void    *pData;
 32     UINT    uDataLen;
 33 } HASHRBTREENODE;
 34 #endif
 35 
 36 
 37 typedef struct HASHRBTREENODE_st {
 38     RBTREENODE  TreeNode;
 39     struct HASHRBTREENODE_st *pNext;
 40 } HASHRBTREENODE;
 41 
 42 typedef struct HASHRBTREE_st {
 43     RBTREE          *pTree;         /* 红黑树的指针 */  
 44     HASHRBTREENODE **ppBucket;     /* 哈希表的索引 */
 45     UINT         uBucketCount;  /* 哈希表索引中桶的数量 */        
 46 } HASHRBTREE;
 47 
 48 HASHRBTREE *HashRBTree_Create(UINT uBucketCount);
 49 void HashRBTree_Destroy(HASHRBTREE *pHashRBTree, DESTROYFUNC DestroyFunc);
 50 
 51 
 52 INT HashRBTree_Insert(HASHRBTREE *pHashRBTree, void *pData, HASHFUNC HashFunc,
 53                       COMPAREFUNC CompareFunc, DESTROYFUNC DestroyFunc);
 54 
 55 INT HashRBTree_Delete(HASHRBTREE *pHashRBTree, void *pData, 
 56                       HASHFUNC HashFunc, 
 57                       COMPAREFUNC CompareFunc,
 58                       DESTROYFUNC DestroyFunc);
 59 
 60 void * HashRBTree_HashFind(HASHRBTREE *pHashRBTree, void *pData, 
 61                            HASHFUNC HashFunc, 
 62                            COMPAREFUNC CompareFunc );
 63 
 64 void * HashRBTree_TreeFind(HASHRBTREE *pHashRBTree, void *pData, 
 65                            COMPAREFUNC CompareFunc );
 66 
 67 void HashRBTree_EnumBegin(HASHRBTREE *pHashRBTree);
 68 
 69 void *HashRBTree_EnumNext(HASHRBTREE *pHashRBTree);
 70 
 71 
 72 
 73 
 74 #ifdef __cplusplus
 75 }
 76 #endif
 77 
 78 #endif /* __HASHRBTREE_H__ */
 79 
 80 
 81 /*
 82  * Copyright (c) 2000-2008
 83  * Author: Weiming Zhou
 84  *
 85  * Permission to use, copy, modify, distribute and sell this software
 86  * and its documentation for any purpose is hereby granted without fee,
 87  * provided that the above copyright notice appear in all copies and
 88  * that both that copyright notice and this permission notice appear
 89  * in supporting documentation.  
 90  */
 91 
 92 #include <stdlib.h>
 93 #include "CapiGlobal.h"
 94 #include "BinTree.h"
 95 #include "RBTree.h"
 96 #include "HashRBTree.h"
 97 
 98 
 99 /**    哈希红黑树的节点创建函数
100 
101     @param    void *pData - 数据指针    
102     @return    static HASHRBTREENODE * - 成功返回创建的节点指针,失败返回NULL    
103 */
104 static HASHRBTREENODE *HashRBTreeNode_Create( void *pData )
105 {
106     HASHRBTREENODE *pNewNode;
107 
108     pNewNode = (HASHRBTREENODE *)malloc(sizeof(HASHRBTREENODE));
109     if ( pNewNode != NULL )
110     {
111         RBTREENODE     *pTreeNode;
112 
113         pTreeNode = &(pNewNode->TreeNode);
114 
115         pTreeNode->pLeft = NULL;
116         pTreeNode->pRight = NULL;
117         pTreeNode->nMagic = RBTREE_COLOR_RED;
118         pTreeNode->pData = pData;
119         pTreeNode->pParent = NULL;
120 
121         pNewNode->pNext = NULL;
122     }
123     return pNewNode;
124 }
125 
126 /**    哈希红黑树的创建函数
127 
128     @param    UINT uBucketNum - 哈希表的bucket数量    
129     @return    HASHRBTREE * - 成功返回哈希红黑树指针,失败返回NULL。    
130 */
131 HASHRBTREE *HashRBTree_Create(UINT uBucketCount)
132 {
133     HASHRBTREE  *pHashRBTree;
134 
135     if ( uBucketCount == 0 )
136     {
137         return NULL;
138     }
139 
140     pHashRBTree = (HASHRBTREE *)malloc( sizeof(HASHRBTREE) );
141     if ( pHashRBTree != NULL )
142     {
143         pHashRBTree->ppBucket = (HASHRBTREENODE **)malloc( uBucketCount 
144             * sizeof(HASHRBTREENODE *) );
145         if ( pHashRBTree->ppBucket != NULL )
146         {
147             pHashRBTree->pTree = RBTree_Create();
148             if ( pHashRBTree->pTree == NULL )
149             {
150                 free( pHashRBTree->ppBucket );
151                 free( pHashRBTree );
152                 pHashRBTree = NULL;
153             }
154             else
155             {
156                 memset(pHashRBTree->ppBucket, 0, uBucketCount * sizeof(HASHRBTREENODE *));
157                 pHashRBTree->uBucketCount = uBucketCount;
158             }
159         }
160         else
161         {
162             free( pHashRBTree );
163             pHashRBTree = NULL;
164         }
165     }
166     return pHashRBTree;
167 }
168 
169 /**    哈希红黑树的释放函数
170 
171     @param    HASHRBTREE *pHashRBTree - 哈希红黑树指针    
172     @param    DESTROYFUNC DestroyFunc - 数据释放函数    
173     @return    void - 无    
174 */
175 void HashRBTree_Destroy(HASHRBTREE *pHashRBTree, DESTROYFUNC DestroyFunc)
176 {
177     /* 哈希红黑树中,我们只要按红黑树的释放方法将所有节点释放即可 */
178     if ( pHashRBTree != NULL && pHashRBTree->pTree != NULL )
179     {
180         RBTree_Destroy( pHashRBTree->pTree, DestroyFunc );
181 
182         /* 释放哈希表时,由于节点已经被释放了, 因此不需要释放节点 */
183         free(pHashRBTree->ppBucket);
184         free(pHashRBTree);
185     }
186 }
187 
188 
189 /**    哈希红黑树的插入函数
190 
191     @param    HASHRBTREE *pHashRBTree - 哈希红黑树指针    
192     @param    void *pData - 数据指针    
193     @param    HASHFUNC HashFunc - 哈希函数    
194     @param    COMPAREFUNC CompareFunc - 数据比较函数    
195     @param    DESTROYFUNC DestroyFunc - 数据释放函数    
196     @return    INT - CAPI_FAILED表示失败,CAPI_SUCCESS表示成功。    
197 */
198 INT HashRBTree_Insert(HASHRBTREE *pHashRBTree, void *pData, HASHFUNC HashFunc,
199                       COMPAREFUNC CompareFunc, DESTROYFUNC DestroyFunc)
200 {
201     UINT        uIndex;
202 
203     INT nRet = CAPI_FAILED;
204     if ( pHashRBTree != NULL )
205     {
206         HASHRBTREENODE  *pNewNode;
207 
208         pNewNode = (HASHRBTREENODE *)HashRBTreeNode_Create( pData );
209         if ( pNewNode == NULL )
210         {
211             return CAPI_FAILED;
212         }
213 
214         /* 先将节点插入到红黑树中 */
215         nRet = RBTree_Inter_Insert(pHashRBTree->pTree, 
216             (RBTREENODE *)pNewNode, CompareFunc);
217         if ( nRet == CAPI_SUCCESS )
218         {
219             HASHRBTREENODE  *pNode;
220 
221             /* 在红黑树中插入成功后,再将其插入到哈希表中 */
222             uIndex = (*HashFunc)( pData, pHashRBTree->uBucketCount );
223             pNode = (HASHRBTREENODE *)(pHashRBTree->ppBucket[uIndex]);
224 
225             /* 在哈希表中查找对应节点 */
226             while ( pNode != NULL )
227             {
228                 if ( (*CompareFunc)( (pNode->TreeNode).pData, pData) == 0 )
229                 {
230                     /* 哈希表中存在相同数据的节点,将节点的数据用新的数据覆盖 */
231                     (*DestroyFunc)( (pNode->TreeNode).pData );
232                     (pNode->TreeNode).pData = pData;
233 
234                     return nRet;
235                 }
236                 pNode = pNode->pNext;
237             }
238 
239             /* 将新生成的节点插入到BUCKET的头部 */
240             pNode = (HASHRBTREENODE *)pHashRBTree->ppBucket[uIndex];
241             pNewNode->pNext = pNode;
242             pHashRBTree->ppBucket[uIndex] = (HASHRBTREENODE *)pNewNode;
243         }
244     }
245 
246     return nRet;
247 }
248 
249 /**    哈希红黑树的删除函数
250 
251     @param    HASHRBTREE *pHashRBTree - 哈希红黑树指针    
252     @param    void *pData - 数据指针    
253     @param    HASHFUNC HashFunc - 哈希函数    
254     @param    COMPAREFUNC CompareFunc - 数据比较函数    
255     @param    DESTROYFUNC DestroyFunc - 数据释放函数    
256     @return    INT - 成功返回CAPI_SUCCESS, 失败返回CAPI_FAILED    
257 */
258 INT HashRBTree_Delete(HASHRBTREE *pHashRBTree, void *pData, 
259                       HASHFUNC HashFunc, 
260                       COMPAREFUNC CompareFunc,
261                       DESTROYFUNC DestroyFunc)
262 {
263     UINT    uIndex;
264     HASHRBTREENODE  *pNode;
265     HASHRBTREENODE  *pPrevNode;
266 
267     uIndex = (*HashFunc)( pData, pHashRBTree->uBucketCount );
268     pNode = (HASHRBTREENODE *)(pHashRBTree->ppBucket[uIndex]);
269     pPrevNode = pNode;
270 
271     /* 在哈希表中删除对应的节点,注意这里因为还要在红黑树中删除对应数据的节点,
272      * 因此节点内存必须在删除红黑树时才能释放.
273      */
274     while ( pNode != NULL )
275     {
276         if ( (*CompareFunc)( (pNode->TreeNode).pData, pData ) == 0 )
277         {
278             if ( pPrevNode == pNode )
279             {
280                 pHashRBTree->ppBucket[uIndex] = pNode->pNext;
281             }
282             else
283             {
284                 pPrevNode->pNext = pNode->pNext;
285             }
286 
287             break;
288         }
289 
290         pPrevNode = pNode;
291         pNode = pNode->pNext;
292     }    
293 
294     /* 在红黑树中将对应节点删除 */
295     return RBTree_Delete(pHashRBTree->pTree, pData, CompareFunc, DestroyFunc);
296 }
297 
298 /**    哈希红黑树的按红黑树查找方法进行查找的函数
299 
300     @param    HASHRBTREE *pHashRBTree - 哈希红黑树指针    
301     @param    void *pData - 要查找的数据    
302     @param    HASHFUNC HashFunc - 哈希函数    
303     @param    COMPAREFUNC CompareFunc - 数据比较函数    
304     @return    void * - 成功返回查找到的数据指针,失败返回NULL    
305 */
306 void * HashRBTree_HashFind(HASHRBTREE *pHashRBTree, void *pData, 
307                        HASHFUNC HashFunc, COMPAREFUNC CompareFunc )
308 {
309     UINT                uIndex;
310     HASHRBTREENODE *    pNode;
311 
312     /* 参数校验 */
313     if ( pHashRBTree == NULL || pData == NULL 
314         || HashFunc == NULL || CompareFunc == NULL )
315     {
316         return NULL;
317     }
318 
319     uIndex = (*HashFunc)( pData, pHashRBTree->uBucketCount );
320     pNode = (HASHRBTREENODE *)(pHashRBTree->ppBucket[uIndex]);
321     
322     /* 在哈希表冲突链中进行查找 */
323     while ( pNode != NULL )
324     {
325         if ( (*CompareFunc)( (pNode->TreeNode).pData, pData) == 0 )
326         {
327             /* 找到了对应的数据,返回找到的数据指针 */
328             return (pNode->TreeNode).pData;
329         }
330         pNode = pNode->pNext;
331     }
332 
333     return NULL;
334 }
335 
336 
337 /**    哈希红黑树的按红黑树查找方法进行查找的函数
338 
339     @param    HASHRBTREE *pHashRBTree - 哈希红黑树指针    
340     @param    void *pData - 要查找的数据    
341     @param    COMPAREFUNC CompareFunc - 数据比较函数    
342     @return    void * - 成功返回查找到的数据指针,失败返回NULL    
343 */
344 void * HashRBTree_TreeFind(HASHRBTREE *pHashRBTree, void *pData, 
345                            COMPAREFUNC CompareFunc )
346 {
347     return RBTree_Find(pHashRBTree->pTree, pData, CompareFunc);
348 }
349 
350 
351 /**    哈希红黑树的逐个节点遍历初始化函数
352 
353     @param    HASHRBTREE *pHashRBTree - 哈希红黑树指针    
354     @return    void - 无    
355 */
356 void HashRBTree_EnumBegin(HASHRBTREE *pHashRBTree)
357 {
358     RBTree_EnumBegin(pHashRBTree->pTree);
359 }
360 
361 
362 /**    哈希红黑树的逐个节点遍历函数,按照红黑树的遍历方法进行遍历
363 
364     @param    HASHRBTREE *pHashRBTree - 哈希红黑树指针    
365     @return    void * - 数据指针    
366 */
367 void *HashRBTree_EnumNext(HASHRBTREE *pHashRBTree)
368 {
369     return RBTree_EnumNext(pHashRBTree->pTree);
370 }
HashRBTree
  1 /*
  2  * Copyright (c) 2000-2008
  3  * Author: Weiming Zhou
  4  *
  5  * Permission to use, copy, modify, distribute and sell this software
  6  * and its documentation for any purpose is hereby granted without fee,
  7  * provided that the above copyright notice appear in all copies and
  8  * that both that copyright notice and this permission notice appear
  9  * in supporting documentation.  
 10  */
 11 
 12 #ifndef __HASHAVLTREE_H__
 13 #define __HASHAVLTREE_H__
 14 
 15 
 16 #ifdef __cplusplus
 17 extern "C" {
 18 #endif
 19 
 20 typedef BINTREEBASENODE AVLTREENODE;
 21 
 22 typedef struct HASHAVLTREE_st {
 23     AVLTREENODE **ppBucket;    /* 索引表指针 */
 24     UINT     uBucketCount;    /* 索引表的大小. */
 25     UINT     uNodeCount;    /* 表中的实际节点个数. */
 26     
 27     UINT        uCurBucketNo;   /* 当前要执行的Bucket序号 */
 28     AVLTREENODE *pCurEntry;      /* 当前bucket中的下一个要执行的节点条目 */ 
 29 } HASHAVLTREE;
 30 
 31 
 32 HASHAVLTREE *HashAVLTree_Create(UINT uBucketCount);
 33 void HashAVLTree_Destroy(HASHAVLTREE *pHashAVLTree, DESTROYFUNC DestroyFunc);
 34 
 35 
 36 INT HashAVLTree_Insert(HASHAVLTREE *pHashAVLTree, void *pData, HASHFUNC HashFunc,
 37                       COMPAREFUNC CompareFunc);
 38 
 39 INT HashAVLTree_Delete(HASHAVLTREE *pHashAVLTree, void *pData, 
 40                       HASHFUNC HashFunc, 
 41                       COMPAREFUNC CompareFunc,
 42                       DESTROYFUNC DestroyFunc);
 43 
 44 void * HashAVLTree_Find(HASHAVLTREE *pHashAVLTree, void *pData, 
 45                        HASHFUNC HashFunc, 
 46                        COMPAREFUNC CompareFunc );
 47 
 48 void HashAVLTree_EnumBegin(HASHAVLTREE *pHashAVLTree);
 49 
 50 void *HashAVLTree_EnumNext(HASHAVLTREE *pHashAVLTree);
 51 
 52 
 53 
 54 
 55 #ifdef __cplusplus
 56 }
 57 #endif
 58 
 59 #endif /* __HASHAVLTREE_H__ */
 60 
 61 
 62 /*
 63  * Copyright (c) 2000-2008
 64  * Author: Weiming Zhou
 65  *
 66  * Permission to use, copy, modify, distribute and sell this software
 67  * and its documentation for any purpose is hereby granted without fee,
 68  * provided that the above copyright notice appear in all copies and
 69  * that both that copyright notice and this permission notice appear
 70  * in supporting documentation.  
 71  */
 72 
 73 #include <windows.h>
 74 #include "capiglobal.h"
 75 #include "BinTree.h"
 76 #include "AVLTree.h"
 77 #include "HashAVLTree.h"
 78 
 79 /**    哈希AVL树的创建函数
 80 
 81     @param    UINT uBucketCount - 哈希AVL树中BUCKET数量    
 82     @return    HASHAVLTREE * - 失败返回NULL,成功返回创建的哈希AVL树指针    
 83 */
 84 HASHAVLTREE *HashAVLTree_Create(UINT uBucketCount)
 85 {
 86     HASHAVLTREE    *pTree;
 87     
 88     if ( uBucketCount == 0 )
 89     {
 90         return NULL;
 91     }
 92     
 93     pTree = (HASHAVLTREE *)malloc( sizeof(HASHAVLTREE) );
 94     if ( pTree == NULL )
 95     {
 96         return NULL;
 97     }
 98     
 99     pTree->uNodeCount = 0;
100     pTree->uBucketCount = uBucketCount;
101     
102     pTree->ppBucket = (AVLTREENODE **)malloc( uBucketCount 
103         * sizeof(AVLTREENODE *));
104     
105     if (pTree->ppBucket == NULL)
106     {
107         free( pTree );
108         return NULL;
109     }
110     
111     memset(pTree->ppBucket, 0, uBucketCount * sizeof(AVLTREENODE *));
112     
113     pTree->pCurEntry = NULL;
114     pTree->uCurBucketNo = 0;
115     
116     return pTree;
117 }
118 
119 /**    哈希AVL树的释放函数
120         将哈希AVL树中所有数据和节点及整个哈希AVL树整体释放掉
121 
122     @param    HASHAVLTREE *pHashAVLTree - 要释放的哈希AVL树指针    
123     @param    DESTROYFUNC DestroyFunc - 数据释放回调函数    
124     @return    void - 无    
125 */
126 void HashAVLTree_Destroy(HASHAVLTREE *pHashAVLTree, DESTROYFUNC DestroyFunc)
127 {
128     AVLTREENODE **ppBucket;
129     AVLTREENODE  *pNode;
130     UINT i;
131     
132     if ( pHashAVLTree == NULL )
133     {
134         return;
135     }
136     ppBucket = pHashAVLTree->ppBucket;
137     for ( i = 0; i < pHashAVLTree->uBucketCount; i++ ) 
138     {
139         pNode = ppBucket[i];
140         BinTreeBaseNode_Destroy(pNode, DestroyFunc);
141     }
142     free(ppBucket);
143     
144     /* 将ppbucket设成空指针以避免哈希表被重新使用时造成内存泄漏 */
145     pHashAVLTree->ppBucket = NULL;
146     
147     free( pHashAVLTree );    
148 }
149 
150 
151 /**    哈希AVL树的插入函数
152 
153     @param    HASHAVLTREE *pHashAVLTree - 哈希AVL树指针    
154     @param    void *pData - 要插入的数据指针    
155     @param    HASHFUNC HashFunc - 哈希函数    
156     @param    COMPAREFUNC CompareFunc - 数据比较回调函数    
157     @return    INT - 失败返回CAPI_FAILED,成功返回CAPI_SUCCESS.    
158 */
159 INT HashAVLTree_Insert(HASHAVLTREE *pHashAVLTree, void *pData, 
160                        HASHFUNC HashFunc, COMPAREFUNC CompareFunc)
161 {
162     UINT    uIndex;
163     
164     if ( pHashAVLTree == NULL || pData == NULL || HashFunc == NULL )
165     {
166         return CAPI_FAILED;
167     }
168     
169     uIndex = (*HashFunc)( pData, pHashAVLTree->uBucketCount );
170     
171     /* 将新节点插入到链表的头部 */
172     AVLTreeNode_Insert(&((pHashAVLTree->ppBucket)[uIndex]), pData, CompareFunc);
173     
174     pHashAVLTree->uNodeCount += 1;
175     
176     return CAPI_SUCCESS;
177 }
178 
179 /**    哈希AVL树的节点删除函数
180 
181     @param    HASHAVLTREE *pHashAVLTree - 哈希AVL树指针    
182     @param    void *pData - 数据指针    
183     @param    HASHFUNC HashFunc - 哈希函数    
184     @param    COMPAREFUNC CompareFunc - 数据比较回调函数    
185     @param    DESTROYFUNC DestroyFunc - 数据释放回调函数    
186     @return    INT - 失败返回CAPI_FAILED,成功返回CAPI_SUCCESS.    
187 */
188 INT HashAVLTree_Delete(HASHAVLTREE *pHashAVLTree, void *pData, 
189                       HASHFUNC HashFunc, 
190                       COMPAREFUNC CompareFunc,
191                       DESTROYFUNC DestroyFunc)
192 {
193     UINT        uIndex;
194     
195     if ( pHashAVLTree == NULL || pData == NULL || HashFunc == NULL 
196         || CompareFunc == NULL )
197     {
198         return CAPI_FAILED;
199     }
200     
201     uIndex = (*HashFunc)( pData, pHashAVLTree->uBucketCount );
202 
203     if ( AVLTreeNode_Delete(&((pHashAVLTree->ppBucket)[uIndex]), pData, 
204         CompareFunc, DestroyFunc) != CAPI_NOT_FOUND )
205     {
206         pHashAVLTree->uNodeCount -= 1;
207     }
208 
209     return CAPI_SUCCESS;
210 }
211 
212 /**    哈希AVL树的查找函数
213 
214     @param    HASHAVLTREE *pHashAVLTree - 哈希AVL树指针    
215     @param    void *pData - 要查找的数据指针    
216     @param    HASHFUNC HashFunc - 哈希函数    
217     @param    COMPAREFUNC CompareFunc - 数据比较回调函数    
218     @return    void * - 失败返回NULL,成功返回找到的节点中的数据指针    
219 */
220 void * HashAVLTree_Find(HASHAVLTREE *pHashAVLTree, void *pData, 
221                        HASHFUNC HashFunc, 
222                        COMPAREFUNC CompareFunc )
223 {
224     UINT            uIndex;
225     AVLTREENODE *   pNode;
226     
227     if ( pHashAVLTree == NULL || HashFunc == NULL || CompareFunc == NULL )
228     {
229         return NULL;
230     }
231     
232     uIndex = (*HashFunc)( pData, pHashAVLTree->uBucketCount );
233     pNode = (pHashAVLTree->ppBucket)[uIndex];
234 
235     return BinTree_Find(pNode, pData, CompareFunc);
236 }
237 
238 
239 /**    哈希AVL树的逐个节点遍历开始函数
240 
241     @param    HASHAVLTREE *pHashAVLTree - 哈希AVL树指针    
242     @return    void - 无    
243 */
244 void HashAVLTree_EnumBegin(HASHAVLTREE *pHashAVLTree)
245 {
246     AVLTREENODE *pCursor;
247 
248     pHashAVLTree->uCurBucketNo = 0;
249     pCursor = pHashAVLTree->ppBucket[0];
250     
251     if ( pCursor != NULL )
252     {
253         while ( pCursor->pLeft != NULL )
254         {
255             pCursor = pCursor->pLeft;
256         }
257     }
258     pHashAVLTree->pCurEntry = pCursor;
259 }
260 
261 /**    哈希AVL树的逐个节点遍历函数
262 
263     @param    HASHAVLTREE *pHashAVLTree - 哈希AVL树指针    
264     @return    void * - 返回遍历的节点数据指针,如果遍历完则返回NULL.    
265 */
266 void *HashAVLTree_EnumNext(HASHAVLTREE *pHashAVLTree)
267 {
268     void *pData;
269     AVLTREENODE *pCursor;
270     
271     pCursor = pHashAVLTree->pCurEntry;
272     while ( pCursor == NULL )
273     {
274         pHashAVLTree->uCurBucketNo += 1;
275         if ( pHashAVLTree->uCurBucketNo >= pHashAVLTree->uBucketCount )
276         {
277             return NULL;
278         }
279         pCursor = pHashAVLTree->ppBucket[pHashAVLTree->uCurBucketNo];
280     }
281     
282     if ( pCursor == NULL )
283     {
284         return NULL;
285     }
286 
287     while ( pCursor->pLeft != NULL )
288     {
289         pCursor = pCursor->pLeft;
290     }
291 
292     pData = pCursor->pData;
293     
294     if ( pCursor->pRight != NULL )
295     {
296         pCursor = pCursor->pRight;
297         while ( pCursor->pLeft != NULL )
298         {
299             pCursor = pCursor->pLeft;
300         }
301     }
302     else
303     {
304         AVLTREENODE *pParent = pCursor->pParent;
305         while ( pParent != NULL && pParent->pRight == pCursor )
306         {
307             pCursor = pParent;
308             pParent = pParent->pParent;
309         }
310         pCursor = pParent;
311     }
312     pHashAVLTree->pCurEntry = pCursor;
313     
314     return pData;    
315 }
HashAVLTree

 

posted on 2016-08-18 20:34  yifi  阅读(278)  评论(0编辑  收藏  举报

导航