Changeset 3562 for trunk/kStuff/include/k/kAvlTmpl/kAvlBase.h
- Timestamp:
- Aug 27, 2007, 12:31:38 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kStuff/include/k/kAvlTmpl/kAvlBase.h
r3560 r3562 34 34 * \#define KAVL_EQUAL_ALLOWED 35 35 * Define this to tell us that equal keys are allowed. 36 * Then Equal keys will be put in a list pointed to by KAVLNODE CORE::pList.36 * Then Equal keys will be put in a list pointed to by KAVLNODE::pList. 37 37 * This is by default not defined. 38 38 * … … 65 65 * three are only required when KAVL_RANGE is defined. 66 66 * 67 * \#define KAVLNODECORE 68 * Define this to the name (typedef) of the AVL core node structure. This 69 * structure must have a pLeft, pRight, Key and uchHeight member. 70 * If KAVL_RANGE is defined a KeyLast is also required. 71 * If KAVL_EQUAL_ALLOWED is defined a pList member is required. 67 * \#define KAVLNODE 68 * Define this to the name (typedef) of the AVL node structure. This 69 * structure must have a mpLeft, mpRight, mKey and mHeight member. 70 * If KAVL_RANGE is defined a mKeyLast is also required. 71 * If KAVL_EQUAL_ALLOWED is defined a mpList member is required. 72 * It's possible to use other member names by redefining the names. 72 73 * 73 74 * \#define KAVLTREEPTR 74 75 * Define this to the name (typedef) of the tree pointer type. This is 75 76 * required when KAVL_OFFSET is defined. When not defined it defaults 76 * to KAVLNODE CORE*.77 * to KAVLNODE *. 77 78 * 78 79 * \#define KAVL_FN … … 92 93 * the instantiated template should have. For instance an inlined scope 93 94 * (private or public) should K_DECL_INLINE(rettype) here. 94 *95 * typedef KAVL_TYPE(PFN,CALLBACK)96 * kAVLDoWithAll requires KAVL_TYPE(PFN,CALLBACK) to be a function pointer97 * to a callback suitable for the DoWithAll method.98 *99 95 * 100 96 * This version of the kAVL tree offers the option of inlining the entire … … 115 111 * Defined Constants And Macros * 116 112 *******************************************************************************/ 117 #define KAVL_HEIGHTOF(pNode) (( unsigned char)((pNode) != NULL ? (pNode)->uchHeight : 0))113 #define KAVL_HEIGHTOF(pNode) ((KU8)((pNode) != NULL ? (pNode)->mHeight : 0)) 118 114 119 115 /** @def KAVL_GET_POINTER … … 157 153 158 154 #ifndef KAVLTREEPTR 159 # define KAVLTREEPTR KAVLNODE CORE*155 # define KAVLTREEPTR KAVLNODE * 160 156 #endif 161 157 162 158 #ifdef KAVL_OFFSET 163 # define KAVL_GET_POINTER(pp) ( (KAVLNODE CORE*)((KIPTR)(pp) + *(pp)) )159 # define KAVL_GET_POINTER(pp) ( (KAVLNODE *)((KIPTR)(pp) + *(pp)) ) 164 160 # define KAVL_GET_POINTER_NULL(pp) ( *(pp) != KAVL_NULL ? KAVL_GET_POINTER(pp) : NULL ) 165 161 # define KAVL_SET_POINTER(pp, p) ( (*(pp)) = ((KIPTR)(p) - (KIPTR)(pp)) ) … … 203 199 * Structures and Typedefs * 204 200 *******************************************************************************/ 205 /* 206 * Two stacks that's used to avoid recursive calls.201 /** 202 * Stack used to avoid recursive calls during insert and removal. 207 203 */ 208 204 typedef struct … … 211 207 KAVLTREEPTR *aEntries[KAVL_MAX_STACK]; 212 208 } KAVL_INT(STACK); 213 214 typedef struct215 {216 unsigned cEntries;217 KAVLNODECORE *aEntries[KAVL_MAX_STACK];218 char achFlags[KAVL_MAX_STACK];219 } KAVL_INT(STACK2);220 209 221 210 … … 275 264 { 276 265 KAVLTREEPTR *ppNode = pStack->aEntries[--pStack->cEntries]; 277 KAVLNODE CORE*pNode = KAVL_GET_POINTER(ppNode);278 KAVLNODE CORE *pLeftNode = KAVL_GET_POINTER_NULL(&pNode->pLeft);279 unsigned char uchLeftHeight = KAVL_HEIGHTOF(pLeftNode);280 KAVLNODE CORE *pRightNode = KAVL_GET_POINTER_NULL(&pNode->pRight);281 unsigned char uchRightHeight = KAVL_HEIGHTOF(pRightNode);282 283 if (u chRightHeight + 1 < uchLeftHeight)266 KAVLNODE *pNode = KAVL_GET_POINTER(ppNode); 267 KAVLNODE *pLeftNode = KAVL_GET_POINTER_NULL(&pNode->mpLeft); 268 KU8 uLeftHeight = KAVL_HEIGHTOF(pLeftNode); 269 KAVLNODE *pRightNode = KAVL_GET_POINTER_NULL(&pNode->mpRight); 270 KU8 uRightHeight = KAVL_HEIGHTOF(pRightNode); 271 272 if (uRightHeight + 1 < uLeftHeight) 284 273 { 285 KAVLNODE CORE *pLeftLeftNode = KAVL_GET_POINTER_NULL(&pLeftNode->pLeft);286 KAVLNODE CORE *pLeftRightNode = KAVL_GET_POINTER_NULL(&pLeftNode->pRight);287 unsigned char uchLeftRightHeight = KAVL_HEIGHTOF(pLeftRightNode);288 289 if (KAVL_HEIGHTOF(pLeftLeftNode) >= u chLeftRightHeight)274 KAVLNODE *pLeftLeftNode = KAVL_GET_POINTER_NULL(&pLeftNode->mpLeft); 275 KAVLNODE *pLeftRightNode = KAVL_GET_POINTER_NULL(&pLeftNode->mpRight); 276 KU8 uLeftRightHeight = KAVL_HEIGHTOF(pLeftRightNode); 277 278 if (KAVL_HEIGHTOF(pLeftLeftNode) >= uLeftRightHeight) 290 279 { 291 KAVL_SET_POINTER_NULL(&pNode-> pLeft, &pLeftNode->pRight);292 KAVL_SET_POINTER(&pLeftNode-> pRight, pNode);293 pLeftNode-> uchHeight = (unsigned char)(1 + (pNode->uchHeight = (unsigned char)(1 + uchLeftRightHeight)));280 KAVL_SET_POINTER_NULL(&pNode->mpLeft, &pLeftNode->mpRight); 281 KAVL_SET_POINTER(&pLeftNode->mpRight, pNode); 282 pLeftNode->mHeight = (KU8)(1 + (pNode->mHeight = (KU8)(1 + uLeftRightHeight))); 294 283 KAVL_SET_POINTER(ppNode, pLeftNode); 295 284 } 296 285 else 297 286 { 298 KAVL_SET_POINTER_NULL(&pLeftNode-> pRight, &pLeftRightNode->pLeft);299 KAVL_SET_POINTER_NULL(&pNode-> pLeft, &pLeftRightNode->pRight);300 KAVL_SET_POINTER(&pLeftRightNode-> pLeft, pLeftNode);301 KAVL_SET_POINTER(&pLeftRightNode-> pRight, pNode);302 pLeftNode-> uchHeight = pNode->uchHeight = uchLeftRightHeight;303 pLeftRightNode-> uchHeight = uchLeftHeight;287 KAVL_SET_POINTER_NULL(&pLeftNode->mpRight, &pLeftRightNode->mpLeft); 288 KAVL_SET_POINTER_NULL(&pNode->mpLeft, &pLeftRightNode->mpRight); 289 KAVL_SET_POINTER(&pLeftRightNode->mpLeft, pLeftNode); 290 KAVL_SET_POINTER(&pLeftRightNode->mpRight, pNode); 291 pLeftNode->mHeight = pNode->mHeight = uLeftRightHeight; 292 pLeftRightNode->mHeight = uLeftHeight; 304 293 KAVL_SET_POINTER(ppNode, pLeftRightNode); 305 294 } 306 295 } 307 else if (u chLeftHeight + 1 < uchRightHeight)296 else if (uLeftHeight + 1 < uRightHeight) 308 297 { 309 KAVLNODE CORE *pRightLeftNode = KAVL_GET_POINTER_NULL(&pRightNode->pLeft);310 unsigned char uchRightLeftHeight = KAVL_HEIGHTOF(pRightLeftNode);311 KAVLNODE CORE *pRightRightNode = KAVL_GET_POINTER_NULL(&pRightNode->pRight);312 313 if (KAVL_HEIGHTOF(pRightRightNode) >= u chRightLeftHeight)298 KAVLNODE *pRightLeftNode = KAVL_GET_POINTER_NULL(&pRightNode->mpLeft); 299 KU8 uRightLeftHeight = KAVL_HEIGHTOF(pRightLeftNode); 300 KAVLNODE *pRightRightNode = KAVL_GET_POINTER_NULL(&pRightNode->mpRight); 301 302 if (KAVL_HEIGHTOF(pRightRightNode) >= uRightLeftHeight) 314 303 { 315 KAVL_SET_POINTER_NULL(&pNode-> pRight, &pRightNode->pLeft);316 KAVL_SET_POINTER(&pRightNode-> pLeft, pNode);317 pRightNode-> uchHeight = (unsigned char)(1 + (pNode->uchHeight = (unsigned char)(1 + uchRightLeftHeight)));304 KAVL_SET_POINTER_NULL(&pNode->mpRight, &pRightNode->mpLeft); 305 KAVL_SET_POINTER(&pRightNode->mpLeft, pNode); 306 pRightNode->mHeight = (KU8)(1 + (pNode->mHeight = (KU8)(1 + uRightLeftHeight))); 318 307 KAVL_SET_POINTER(ppNode, pRightNode); 319 308 } 320 309 else 321 310 { 322 KAVL_SET_POINTER_NULL(&pRightNode-> pLeft, &pRightLeftNode->pRight);323 KAVL_SET_POINTER_NULL(&pNode-> pRight, &pRightLeftNode->pLeft);324 KAVL_SET_POINTER(&pRightLeftNode-> pRight, pRightNode);325 KAVL_SET_POINTER(&pRightLeftNode-> pLeft, pNode);326 pRightNode-> uchHeight = pNode->uchHeight = uchRightLeftHeight;327 pRightLeftNode-> uchHeight = uchRightHeight;311 KAVL_SET_POINTER_NULL(&pRightNode->mpLeft, &pRightLeftNode->mpRight); 312 KAVL_SET_POINTER_NULL(&pNode->mpRight, &pRightLeftNode->mpLeft); 313 KAVL_SET_POINTER(&pRightLeftNode->mpRight, pRightNode); 314 KAVL_SET_POINTER(&pRightLeftNode->mpLeft, pNode); 315 pRightNode->mHeight = pNode->mHeight = uRightLeftHeight; 316 pRightLeftNode->mHeight = uRightHeight; 328 317 KAVL_SET_POINTER(ppNode, pRightLeftNode); 329 318 } … … 331 320 else 332 321 { 333 register unsigned char uchHeight = (unsigned char)(K_MAX(uchLeftHeight, uchRightHeight) + 1);334 if (u chHeight == pNode->uchHeight)322 KU8 uHeight = (KU8)(K_MAX(uLeftHeight, uRightHeight) + 1); 323 if (uHeight == pNode->mHeight) 335 324 break; 336 pNode-> uchHeight = uchHeight;325 pNode->mHeight = uHeight; 337 326 } 338 327 } … … 359 348 * Rebalance the tree. 360 349 */ 361 KAVL_DECL(KBOOL) KAVL_FN(Insert)(KAVLTREEPTR *ppTree, KAVLNODE CORE*pNode)350 KAVL_DECL(KBOOL) KAVL_FN(Insert)(KAVLTREEPTR *ppTree, KAVLNODE *pNode) 362 351 { 363 KAVL_INT(STACK) 364 KAVLTREEPTR 365 register KAVLKEY Key = pNode->Key;352 KAVL_INT(STACK) AVLStack; 353 KAVLTREEPTR *ppCurNode = ppTree; 354 register KAVLKEY Key = pNode->mKey; 366 355 #ifdef KAVL_RANGE 367 register KAVLKEY KeyLast = pNode->KeyLast; 368 #endif 369 register KAVLNODECORE *pCurNode; 370 371 AVLStack.cEntries = 0; 356 register KAVLKEY KeyLast = pNode->mKeyLast; 357 #endif 372 358 373 359 #ifdef KAVL_RANGE 374 360 if (Key > KeyLast) 375 361 return false; 376 #else 377 K_NOREF(Key); 378 #endif 379 362 #endif 363 364 AVLStack.cEntries = 0; 380 365 while (*ppCurNode != KAVL_NULL) 381 366 { 382 pCurNode = KAVL_GET_POINTER(ppCurNode);367 register KAVLNODE *pCurNode = KAVL_GET_POINTER(ppCurNode); 383 368 384 369 kHlpAssert(AVLStack.cEntries < KAVL_MAX_STACK); 385 370 AVLStack.aEntries[AVLStack.cEntries++] = ppCurNode; 386 371 #ifdef KAVL_EQUAL_ALLOWED 387 if (KAVL_R_IS_IDENTICAL(pCurNode-> Key, Key, pCurNode->KeyLast, KeyLast))372 if (KAVL_R_IS_IDENTICAL(pCurNode->mKey, Key, pCurNode->mKeyLast, KeyLast)) 388 373 { 389 374 /* 390 375 * If equal then we'll use a list of equal nodes. 391 376 */ 392 pNode-> pLeft = pNode->pRight = KAVL_NULL;393 pNode-> uchHeight = 0;394 KAVL_SET_POINTER_NULL(&pNode-> pList, &pCurNode->pList);395 KAVL_SET_POINTER(&pCurNode-> pList, pNode);377 pNode->mpLeft = pNode->mpRight = KAVL_NULL; 378 pNode->mHeight = 0; 379 KAVL_SET_POINTER_NULL(&pNode->mpList, &pCurNode->mpList); 380 KAVL_SET_POINTER(&pCurNode->mpList, pNode); 396 381 return K_TRUE; 397 382 } 398 383 #endif 399 384 #ifdef KAVL_CHECK_FOR_EQUAL_INSERT 400 if (KAVL_R_IS_INTERSECTING(pCurNode-> Key, Key, pCurNode->KeyLast, KeyLast))385 if (KAVL_R_IS_INTERSECTING(pCurNode->mKey, Key, pCurNode->mKeyLast, KeyLast)) 401 386 return K_FALSE; 402 387 #endif 403 if (KAVL_G(pCurNode-> Key, Key))404 ppCurNode = &pCurNode-> pLeft;388 if (KAVL_G(pCurNode->mKey, Key)) 389 ppCurNode = &pCurNode->mpLeft; 405 390 else 406 ppCurNode = &pCurNode-> pRight;391 ppCurNode = &pCurNode->mpRight; 407 392 } 408 393 409 pNode-> pLeft = pNode->pRight = KAVL_NULL;394 pNode->mpLeft = pNode->mpRight = KAVL_NULL; 410 395 #ifdef KAVL_EQUAL_ALLOWED 411 pNode-> pList = KAVL_NULL;412 #endif 413 pNode-> uchHeight = 1;396 pNode->mpList = KAVL_NULL; 397 #endif 398 pNode->mHeight = 1; 414 399 KAVL_SET_POINTER(ppCurNode, pNode); 415 400 … … 458 443 * return pointer to the removed node (if found). 459 444 */ 460 KAVL_DECL(KAVLNODE CORE*) KAVL_FN(Remove)(KAVLTREEPTR *ppTree, KAVLKEY Key)445 KAVL_DECL(KAVLNODE *) KAVL_FN(Remove)(KAVLTREEPTR *ppTree, KAVLKEY Key) 461 446 { 462 KAVL_INT(STACK) 463 KAVLTREEPTR 464 register KAVLNODE CORE*pDeleteNode;447 KAVL_INT(STACK) AVLStack; 448 KAVLTREEPTR *ppDeleteNode = ppTree; 449 register KAVLNODE *pDeleteNode; 465 450 466 451 AVLStack.cEntries = 0; 467 468 452 for (;;) 469 453 { … … 474 458 kHlpAssert(AVLStack.cEntries < KAVL_MAX_STACK); 475 459 AVLStack.aEntries[AVLStack.cEntries++] = ppDeleteNode; 476 if (KAVL_E(pDeleteNode-> Key, Key))460 if (KAVL_E(pDeleteNode->mKey, Key)) 477 461 break; 478 462 479 if (KAVL_G(pDeleteNode-> Key, Key))480 ppDeleteNode = &pDeleteNode-> pLeft;463 if (KAVL_G(pDeleteNode->mKey, Key)) 464 ppDeleteNode = &pDeleteNode->mpLeft; 481 465 else 482 ppDeleteNode = &pDeleteNode-> pRight;466 ppDeleteNode = &pDeleteNode->mpRight; 483 467 } 484 468 485 if (pDeleteNode-> pLeft != KAVL_NULL)469 if (pDeleteNode->mpLeft != KAVL_NULL) 486 470 { 487 471 /* find the rightmost node in the left tree. */ 488 const unsigned 489 KAVLTREEPTR *ppLeftLeast = &pDeleteNode->pLeft;490 register KAVLNODE CORE*pLeftLeast = KAVL_GET_POINTER(ppLeftLeast);491 492 while (pLeftLeast-> pRight != KAVL_NULL)472 const unsigned iStackEntry = AVLStack.cEntries; 473 KAVLTREEPTR *ppLeftLeast = &pDeleteNode->mpLeft; 474 register KAVLNODE *pLeftLeast = KAVL_GET_POINTER(ppLeftLeast); 475 476 while (pLeftLeast->mpRight != KAVL_NULL) 493 477 { 494 478 kHlpAssert(AVLStack.cEntries < KAVL_MAX_STACK); 495 479 AVLStack.aEntries[AVLStack.cEntries++] = ppLeftLeast; 496 ppLeftLeast = &pLeftLeast-> pRight;480 ppLeftLeast = &pLeftLeast->mpRight; 497 481 pLeftLeast = KAVL_GET_POINTER(ppLeftLeast); 498 482 } 499 483 500 484 /* link out pLeftLeast */ 501 KAVL_SET_POINTER_NULL(ppLeftLeast, &pLeftLeast-> pLeft);485 KAVL_SET_POINTER_NULL(ppLeftLeast, &pLeftLeast->mpLeft); 502 486 503 487 /* link it in place of the delete node. */ 504 KAVL_SET_POINTER_NULL(&pLeftLeast-> pLeft, &pDeleteNode->pLeft);505 KAVL_SET_POINTER_NULL(&pLeftLeast-> pRight, &pDeleteNode->pRight);506 pLeftLeast-> uchHeight = pDeleteNode->uchHeight;488 KAVL_SET_POINTER_NULL(&pLeftLeast->mpLeft, &pDeleteNode->mpLeft); 489 KAVL_SET_POINTER_NULL(&pLeftLeast->mpRight, &pDeleteNode->mpRight); 490 pLeftLeast->mHeight = pDeleteNode->mHeight; 507 491 KAVL_SET_POINTER(ppDeleteNode, pLeftLeast); 508 AVLStack.aEntries[iStackEntry] = &pLeftLeast-> pLeft;492 AVLStack.aEntries[iStackEntry] = &pLeftLeast->mpLeft; 509 493 } 510 494 else 511 495 { 512 KAVL_SET_POINTER_NULL(ppDeleteNode, &pDeleteNode-> pRight);496 KAVL_SET_POINTER_NULL(ppDeleteNode, &pDeleteNode->mpRight); 513 497 AVLStack.cEntries--; 514 498 }
Note:
See TracChangeset
for help on using the changeset viewer.