zoukankan      html  css  js  c++  java
  • 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] != ''; i++ )
    510     {
    511         hashval += hashval << 3;
    512         hashval += s[i] ;
    513     }
    514 #endif
    515     j = 0;
    516     ret = 0;
    517     while ( *s != '' )
    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 != '' )
    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
    爱程序 不爱bug 爱生活 不爱黑眼圈 我和你们一样 我和你们不一样 我不是凡客 我要做geek
  • 相关阅读:
    关于信号量sem_wait的整理(转)
    WPF版的正则表达式工具开发完成
    F#中的Tuples、函数类型和参数柯里化
    一个WPF版的类Vista的地址栏控件Breadcrumb Bar
    多文档版的的正则表达式工具
    Reactive Extensions for .NET (Rx)
    解决下载的电子书中换行的问题
    WPF下的语法高亮控件——AvalonEdit
    把正则表达式测试工具界面更新为Aero效果的了
    Blend可以支持.net 4.0的工程了
  • 原文地址:https://www.cnblogs.com/yifi/p/5785274.html
Copyright © 2011-2022 走看看