书上的代码 整理一下
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] != '