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 }
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 }
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 }
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 }
爱程序 不爱bug
爱生活 不爱黑眼圈
我和你们一样 我和你们不一样
我不是凡客 我要做geek