00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00033 #ifndef tree_temp_offset
00034 #error The 'tree_temp_offset' template parameter was not defined.
00035 #endif
00036
00037 #ifndef tree_temp_multiple
00038 #error The 'tree_temp_multiple' template parameter was not defined.
00039 #endif
00040
00041
00042 #define tree_fixup(root) \
00043 {\
00044 if( (root)->balance < 0 )\
00045 {\
00046 (root)->left->balance = 0;\
00047 (root)->right->balance = 1;\
00048 }\
00049 else if( (root)->balance > 0 )\
00050 {\
00051 (root)->left->balance = -1;\
00052 (root)->right->balance = 0;\
00053 }\
00054 else\
00055 {\
00056 (root)->left->balance = 0;\
00057 (root)->right->balance = 0;\
00058 }\
00059 (root)->balance = 0;\
00060 }
00061
00062
00063
00064
00065 #define tree_swl(root)\
00066 {\
00067 ctlt_node_type(tree_temp_offset,tree_temp_multiple) *a_swr = (root);\
00068 ctlt_node_type(tree_temp_offset,tree_temp_multiple) *b_swr = a_swr->right;\
00069 (root) = b_swr;\
00070 a_swr->right = b_swr->left;\
00071 b_swr->left = a_swr;\
00072 }
00073
00074
00075
00076
00077 #define tree_swr(root)\
00078 {\
00079 ctlt_node_type(tree_temp_offset,tree_temp_multiple) *a_swr = (root);\
00080 ctlt_node_type(tree_temp_offset,tree_temp_multiple) *b_swr = a_swr->left;\
00081 (root) = b_swr;\
00082 a_swr->left = b_swr->right;\
00083 b_swr->right = a_swr;\
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093 #define tree_compare( tree, n1, n2 ) (tree)->compare( ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, (tree),(n1)), ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, (tree),(n2)) )
00094
00095
00096
00097
00098
00099
00100
00101 #define tree_copy( treedst, dstroot, treesrc ) { (treedst)->root = (dstroot); (treedst)->compare = (treesrc)->compare; ctlt_offset_for_relative(tree_temp_offset,(treedst)->data_offset = (treesrc)->data_offset;) (treedst)->size = 0; }
00102
00103
00104
00105
00106
00107
00108 #define tree_integrate( treedst, treesrc ) { (treedst)->size += (treesrc)->size; (treedst)->found = (treesrc)->found; }
00109
00110 static bool ctl_tree_(tree_temp_offset,tree_temp_multiple, _insert )( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node );
00111 static int ctl_tree_(tree_temp_offset,tree_temp_multiple, _remove )( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node );
00112 static int ctl_tree_(tree_temp_offset,tree_temp_multiple, _removeroot )( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree );
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 static bool ctl_tree_(tree_temp_offset,tree_temp_multiple, _insert )( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node )
00130 {
00131
00132 int diff;
00133
00134
00135 assert( node != tree->root );
00136 tree->found = NULL;
00137 node->left = 0;
00138 node->right = 0;
00139 node->balance = 0;
00140
00141 if (!tree->root)
00142 {
00143 tree->root = node;
00144 tree->size++;
00145 return true;
00146 }
00147 diff = tree_compare( tree, tree->root, node );
00148 if( diff > 0 )
00149 {
00150
00151 if (tree->root->left)
00152 {
00153 ctl_tree(tree_temp_offset,tree_temp_multiple) left_sutree;
00154 tree_copy( &left_sutree, tree->root->left, tree );
00155 if (ctl_tree_(tree_temp_offset,tree_temp_multiple, _insert ) (&left_sutree, node))
00156 {
00157 int tmpBalance = tree->root->balance--;
00158 tree_integrate( tree, &left_sutree );
00159 if( 0 == tmpBalance )
00160 return true;
00161 if( 1 == tmpBalance )
00162 return false;
00163 if (tree->root->left->balance < 0)
00164 {
00165 tree_swr (tree->root);
00166 tree->root->balance = 0;
00167 tree->root->right->balance = 0;
00168 }
00169 else
00170 {
00171 tree_swl (tree->root->left);
00172 tree_swr (tree->root);
00173 tree_fixup (tree->root);
00174 }
00175 }
00176 else
00177 {
00178 tree_integrate( tree, &left_sutree );
00179 tree->root->left = left_sutree.root;
00180 }
00181 return false;
00182 }
00183 else
00184 {
00185 tree->root->left = node;
00186 (tree)->size++;
00187 if (tree->root->balance--)
00188 return false;
00189 return true;
00190 }
00191 }
00192 #if ctlt_multi_value(tree_temp_multiple)
00193 else
00194 #else
00195 else if( diff < 0 )
00196 #endif
00197 {
00198
00199 if (tree->root->right)
00200 {
00201 ctl_tree(tree_temp_offset,tree_temp_multiple) right_sutree;
00202 tree_copy( &right_sutree, tree->root->right, tree );
00203 if (ctl_tree_(tree_temp_offset,tree_temp_multiple, _insert ) (&right_sutree, node))
00204 {
00205 int tmpBalance = tree->root->balance++;
00206 tree_integrate( tree, &right_sutree );
00207 if( -1 == tmpBalance )
00208 return false;
00209 if( 0 == tmpBalance )
00210 return true;
00211 if (tree->root->right->balance > 0)
00212 {
00213 tree_swl (tree->root);
00214 tree->root->balance = 0;
00215 tree->root->left->balance = 0;
00216 }
00217 else
00218 {
00219 tree_swr (tree->root->right);
00220 tree_swl (tree->root);
00221 tree_fixup (tree->root);
00222 }
00223 }
00224 else
00225 {
00226 tree_integrate( tree, &right_sutree );
00227 tree->root->right = right_sutree.root;
00228 }
00229 return false;
00230 }
00231 else
00232 {
00233 tree->root->right = node;
00234 (tree)->size++;
00235 if (tree->root->balance++)
00236 return false;
00237 return true;
00238 }
00239 }
00240 #if ctlt_multi_not_value(tree_temp_multiple)
00241
00242 tree->found = tree->root;
00243 return false;
00244 #endif
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 static int ctl_tree_(tree_temp_offset,tree_temp_multiple, _removeroot )( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree )
00258 {
00259 int ch;
00260 ctlt_node_type(tree_temp_offset,tree_temp_multiple) *node;
00261 ctlt_node_type(tree_temp_offset,tree_temp_multiple) *root = tree->root;
00262
00263 assert(root);
00264
00265 if (!root->left)
00266 {
00267 (tree)->found = root;
00268 (tree)->size--;
00269 if (!root->right)
00270 {
00271 tree->root = 0;
00272 return -1;
00273 }
00274 tree->root = root->right;
00275 return -1;
00276 }
00277 if (!root->right)
00278 {
00279 (tree)->found = root;
00280 tree->root = root->left;
00281 (tree)->size--;
00282 return -1;
00283 }
00284
00285 if (root->balance < 0)
00286 {
00287
00288 node = root->left;
00289 while (node->right)
00290 node = node->right;
00291 }
00292 else
00293 {
00294
00295 node = root->right;
00296 while (node->left)
00297 node = node->left;
00298 }
00299
00300 ch = ctl_tree_(tree_temp_offset,tree_temp_multiple, _remove ) (tree, node);
00301 root = tree->root;
00302 node->left = root->left;
00303 node->right = root->right;
00304 node->balance = root->balance;
00305 tree->root = node;
00306 if (node->balance == 0)
00307 return ch;
00308 return 0;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318 static int ctl_tree_(tree_temp_offset,tree_temp_multiple, _remove )( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node )
00319 {
00320
00321
00322 int b;
00323 if (tree->root == node)
00324 return ctl_tree_(tree_temp_offset,tree_temp_multiple, _removeroot ) (tree);
00325 b = tree_compare( tree, tree->root, node );
00326 if (b >= 0)
00327 {
00328
00329 int ch;
00330 ctl_tree(tree_temp_offset,tree_temp_multiple) left_sutree;
00331 tree_copy( &left_sutree, tree->root->left, tree );
00332 if (left_sutree.root )
00333 {
00334 ch = ctl_tree_(tree_temp_offset,tree_temp_multiple, _remove ) (&left_sutree, node);
00335 tree_integrate( tree, &left_sutree );
00336 tree->root->left = left_sutree.root;
00337 if (ch)
00338 {
00339 int tmpBalance = tree->root->balance++;
00340 if( -1 == tmpBalance)
00341 return -1;
00342 if( 0 == tmpBalance)
00343 return 0;
00344 tmpBalance = tree->root->right->balance;
00345 if( 0 == tmpBalance )
00346 {
00347 tree_swl (tree->root);
00348 tree->root->balance = -1;
00349 tree->root->left->balance = 1;
00350 return 0;
00351 }
00352 if( 1 == tmpBalance )
00353 {
00354 tree_swl (tree->root);
00355 tree->root->balance = 0;
00356 tree->root->left->balance = 0;
00357 return -1;
00358 }
00359 tree_swr (tree->root->right);
00360 tree_swl (tree->root);
00361 tree_fixup (tree->root);
00362 return -1;
00363 }
00364 }
00365 }
00366 if (b <= 0)
00367 {
00368
00369 int ch;
00370 ctl_tree(tree_temp_offset,tree_temp_multiple) right_sutree;
00371 tree_copy( &right_sutree, tree->root->right, tree );
00372 if (right_sutree.root )
00373 {
00374 ch = ctl_tree_(tree_temp_offset,tree_temp_multiple, _remove ) (&right_sutree, node);
00375 tree_integrate( tree, &right_sutree );
00376 tree->root->right = right_sutree.root;
00377 if (ch)
00378 {
00379 int tmpBalance = tree->root->balance--;
00380 if( 1 == tmpBalance )
00381 return -1;
00382 if( 0 == tmpBalance )
00383 return 0;
00384
00385 tmpBalance = tree->root->left->balance;
00386 if( 0 == tmpBalance )
00387 {
00388 tree_swr (tree->root);
00389 tree->root->balance = 1;
00390 tree->root->right->balance = -1;
00391 return 0;
00392 }
00393 if( -1 == tmpBalance )
00394 {
00395 tree_swr (tree->root);
00396 tree->root->balance = 0;
00397 tree->root->right->balance = 0;
00398 return -1;
00399 }
00400 tree_swl (tree->root->left);
00401 tree_swr (tree->root);
00402 tree_fixup (tree->root);
00403 return -1;
00404 }
00405 }
00406 }
00407 return 0;
00408 }
00409
00418 ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, insert)( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, ctlt_offset_type(tree_temp_offset)* data )
00419 {
00420 ppDebug(size_t size = tree->size;)
00421 ctlt_node_type(tree_temp_offset,tree_temp_multiple) *node = ctl_tree_data_to_node(tree_temp_offset,tree_temp_multiple, tree,data);
00422 ctl_tree_(tree_temp_offset,tree_temp_multiple, _insert )(tree, node);
00423 if( !tree->found )
00424 {
00425 assert( size < tree->size );
00426 return data;
00427 }
00428 return ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,tree->found);
00429 }
00430
00439 ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, remove)( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, ctlt_offset_type(tree_temp_offset)* data )
00440 {
00441 data = (ctlt_offset_type(tree_temp_offset)*)ctl_tree_(tree_temp_offset,tree_temp_multiple, find)( tree, data );
00442 if( data )
00443 {
00444 ppDebug(size_t size = tree->size;)
00445 ctlt_node_type(tree_temp_offset,tree_temp_multiple) *node = ctl_tree_data_to_node(tree_temp_offset,tree_temp_multiple, tree,data);
00446 ctl_tree_(tree_temp_offset,tree_temp_multiple, _remove )( tree, node );
00447 assert( size > tree->size );
00448 return ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,node);
00449 }
00450 return NULL;
00451 }
00452
00461 ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, unlink)( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, ctlt_offset_type(tree_temp_offset)* data )
00462 {
00463 assertobjptr( tree );
00464 assertptr( data, sizeof(void*) );
00465 {
00466 ppDebug(size_t size = tree->size;)
00467 ctlt_node_type(tree_temp_offset,tree_temp_multiple) *node = ctl_tree_data_to_node(tree_temp_offset,tree_temp_multiple, tree,data);
00468 ctl_tree_(tree_temp_offset,tree_temp_multiple, _remove )( tree, node );
00469 assert( size > tree->size );
00470 return ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,node);
00471 }
00472 }
00473
00479 void ctl_tree_(tree_temp_offset,tree_temp_multiple, recurseunlink)( ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node )
00480 {
00481 if( node->left )
00482 ctl_tree_(tree_temp_offset,tree_temp_multiple, recurseunlink)( node->left );
00483 if( node->right )
00484 ctl_tree_(tree_temp_offset,tree_temp_multiple, recurseunlink)( node->right );
00485 node->left = node->right = NULL;
00486 }
00487
00493 void ctl_tree_(tree_temp_offset,tree_temp_multiple, reset)( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree )
00494 {
00495 if( tree->root )
00496 ctl_tree_(tree_temp_offset,tree_temp_multiple, recurseunlink)( tree->root );
00497 tree->root = NULL;
00498 tree->size = 0;
00499 }
00500
00507 static size_t ctl_tree_(tree_temp_offset,tree_temp_multiple, recursetally)( ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node )
00508 {
00509 if( node )
00510 return 1 + ctl_tree_(tree_temp_offset,tree_temp_multiple, recursetally( node->left )) + ctl_tree_(tree_temp_offset,tree_temp_multiple, recursetally)( node->right );
00511 return 0;
00512 }
00513
00520 size_t ctl_tree_(tree_temp_offset,tree_temp_multiple, tally)( const ctl_tree(tree_temp_offset,tree_temp_multiple)* tree )
00521 {
00522
00523
00524
00525
00526 size_t size = ctl_tree_(tree_temp_offset,tree_temp_multiple, recursetally)( tree->root );
00527 assert( size == tree->size );
00528 return size;
00529 }
00530
00538 static size_t ctl_tree_(tree_temp_offset,tree_temp_multiple, recursedepth)( const ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node, size_t currDepth )
00539 {
00540 if( node )
00541 {
00542 size_t d1 = ctl_tree_(tree_temp_offset,tree_temp_multiple, recursedepth)( node->left, currDepth+1 );
00543 size_t d2 = ctl_tree_(tree_temp_offset,tree_temp_multiple, recursedepth)( node->right, currDepth+1 );
00544 return max(d1,d2);
00545 }
00546 return currDepth;
00547 }
00548
00559 size_t ctl_tree_(tree_temp_offset,tree_temp_multiple, depth)( const ctl_tree(tree_temp_offset,tree_temp_multiple)* tree )
00560 {
00561 return ctl_tree_(tree_temp_offset,tree_temp_multiple, recursedepth)( tree->root, 1 );
00562 }
00563
00570 const ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, front)( const ctl_tree(tree_temp_offset,tree_temp_multiple)* tree )
00571 {
00572 const ctlt_node_type(tree_temp_offset,tree_temp_multiple) *node = tree->root;
00573 if( !node )
00574 return NULL;
00575 while( node->left )
00576 node = node->left;
00577 return ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,node);
00578 }
00579
00586 const ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, back)( const ctl_tree(tree_temp_offset,tree_temp_multiple)* tree )
00587 {
00588 const ctlt_node_type(tree_temp_offset,tree_temp_multiple) *node = tree->root;
00589 if( !node )
00590 return NULL;
00591 while( node->left )
00592 node = node->left;
00593 return ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,node);
00594 }
00595
00603 const ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, find)( const ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, const ctlt_offset_type(tree_temp_offset)* data )
00604 {
00605 tree_compare compare = tree->compare;
00606 const ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node = tree->root;
00607 while( node )
00608 {
00609 int diff = compare( data, ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,node) );
00610 if( diff > 0 )
00611 node = node->right;
00612 else if( diff < 0 )
00613 node = node->left;
00614 else
00615 return ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,node);
00616 }
00617 return NULL;
00618 }
00619
00626 ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, pop_front)( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree )
00627 {
00628 ctlt_node_type(tree_temp_offset,tree_temp_multiple) *node = tree->root;
00629 if( !node )
00630 return NULL;
00631 while( node->left )
00632 node = node->left;
00633 ctl_tree_(tree_temp_offset,tree_temp_multiple, _remove )( tree, node );
00634 return ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,node);
00635 }
00636
00643 ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, pop_back)( ctl_tree(tree_temp_offset,tree_temp_multiple)* tree )
00644 {
00645 ctlt_node_type(tree_temp_offset,tree_temp_multiple) *node = tree->root;
00646 if( !node )
00647 return NULL;
00648 while( node->right )
00649 node = node->right;
00650 ctl_tree_(tree_temp_offset,tree_temp_multiple, _remove )( tree, node );
00651 return ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,node);
00652 }
00653
00661 const ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_begin)( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator )* stack, const ctl_tree(tree_temp_offset,tree_temp_multiple)* tree )
00662 {
00663 const ctlt_node_type(tree_temp_offset,tree_temp_multiple) *node = tree->root;
00664 stack->tree = tree;
00665 stack->sp = stack->stack;
00666 *stack->sp++ = NULL;
00667 while( node )
00668 {
00669 *stack->sp++ = node;
00670 node = node->left;
00671 }
00672
00673 assert( memberof(stack->stack,stack->sp) );
00674 return ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_next)( stack );
00675 }
00676
00685 static bool ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_begin_from_no_iterate)( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator )* stack, const ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, const ctlt_offset_type(tree_temp_offset)* data )
00686 {
00687 tree_compare compare = tree->compare;
00688 const ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node = tree->root;
00689 stack->tree = tree;
00690 stack->sp = stack->stack;
00691 *stack->sp++ = NULL;
00692 while( node )
00693 {
00694 int diff = compare( data, ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,node) );
00695 if( diff > 0 )
00696 {
00697 node = node->right;
00698 }
00699 else
00700 #if ctlt_multi_not_value(tree_temp_multiple)
00701 if( diff < 0 )
00702 #endif
00703 {
00704 *stack->sp++ = node;
00705 node = node->left;
00706 }
00707 #if ctlt_multi_not_value(tree_temp_multiple)
00708 else
00709 {
00710
00711 *stack->sp++ = node;
00712
00713 assert( memberof(stack->stack,stack->sp) );
00714 return true;
00715 }
00716 #endif
00717 }
00718
00719 assert( memberof(stack->stack,stack->sp) );
00720 return false;
00721 }
00722
00731 const ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_begin_from)( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator )* stack, const ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, const ctlt_offset_type(tree_temp_offset)* data )
00732 {
00733
00734 if( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_begin_from_no_iterate)( stack, tree, data ) )
00735 return ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_next)( stack );
00736
00737
00738 {
00739 tree_compare compare = tree->compare;
00740 const ctlt_offset_type(tree_temp_offset)* curr = ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_next)( stack );
00741 while( curr && compare( data, curr ) > 0 )
00742 curr = ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_next)( stack );
00743 return curr;
00744 }
00745 }
00746
00754 const ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_next)( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator )* stack )
00755 {
00756
00757 const ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node = *--stack->sp;
00758 if( node )
00759 {
00760 if( node->right )
00761 {
00762
00763 const ctlt_node_type(tree_temp_offset,tree_temp_multiple)* next = node->right;
00764 while( next )
00765 {
00766 *stack->sp++ = next;
00767 next = next->left;
00768 }
00769 }
00770 stack->node = node;
00771 return ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, stack->tree,node);
00772 }
00773 stack->node = NULL;
00774 return NULL;
00775 }
00776
00784 const ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_rbegin)( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator )* stack, const ctl_tree(tree_temp_offset,tree_temp_multiple) *tree )
00785 {
00786 const ctlt_node_type(tree_temp_offset,tree_temp_multiple) *node = tree->root;
00787 stack->tree = tree;
00788 stack->bReverse = true;
00789 stack->sp = stack->stack;
00790 *stack->sp++ = NULL;
00791 while( node )
00792 {
00793 *stack->sp++ = node;
00794 node = node->right;
00795 }
00796
00797 assert( memberof(stack->stack,stack->sp) );
00798 return ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_prev)( stack );
00799 }
00800
00809 static bool ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_rbegin_from_no_iterate)( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator )* stack, const ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, const ctlt_offset_type(tree_temp_offset)* data )
00810 {
00811 tree_compare compare = tree->compare;
00812 const ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node = tree->root;
00813 stack->tree = tree;
00814 stack->bReverse = true;
00815 stack->sp = stack->stack;
00816 *stack->sp++ = NULL;
00817 while( node )
00818 {
00819 int diff = compare( data, ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,node) );
00820 if( diff < 0 )
00821 {
00822 node = node->left;
00823 }
00824 else
00825 #if ctlt_multi_not_value(tree_temp_multiple)
00826 if( diff > 0 )
00827 #endif
00828 {
00829 *stack->sp++ = node;
00830 node = node->right;
00831 }
00832 #if ctlt_multi_not_value(tree_temp_multiple)
00833 else
00834 {
00835
00836 *stack->sp++ = node;
00837
00838 assert( memberof(stack->stack,stack->sp) );
00839 return true;
00840 }
00841 #endif
00842 }
00843
00844 assert( memberof(stack->stack,stack->sp) );
00845 return false;
00846 }
00847
00856 const ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_rbegin_from)( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator )* stack, const ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, const ctlt_offset_type(tree_temp_offset)* data )
00857 {
00858 if( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_rbegin_from_no_iterate)( stack, tree, data ) )
00859 return ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_prev)( stack );
00860
00861 {
00862 tree_compare compare = tree->compare;
00863 const ctlt_offset_type(tree_temp_offset)* curr = ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_prev)( stack );
00864 while( curr && compare( data, curr ) < 0 )
00865 curr = ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_prev)( stack );
00866 return curr;
00867 }
00868 }
00869
00876 const ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_prev)( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator )* stack )
00877 {
00878
00879 const ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node = *--stack->sp;
00880 if( node )
00881 {
00882 if( node->left )
00883 {
00884
00885 const ctlt_node_type(tree_temp_offset,tree_temp_multiple)* prev = node->left;
00886 while( prev )
00887 {
00888 *stack->sp++ = prev;
00889 prev = prev->right;
00890 }
00891 }
00892 stack->node = node;
00893 return ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, stack->tree,node);
00894 }
00895 stack->node = NULL;
00896 return NULL;
00897 }
00898
00906 const ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, unlink_curr)( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator )* stack )
00907 {
00908 if( stack->node )
00909 {
00910 ctl_tree_(tree_temp_offset,tree_temp_multiple, _remove )( (ctl_tree(tree_temp_offset,tree_temp_multiple)*)stack->tree, (ctlt_node_type(tree_temp_offset,tree_temp_multiple)*)stack->node );
00911 return ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, stack->tree,stack->node);
00912 }
00913 return NULL;
00914 }
00915
00923 const ctlt_offset_type(tree_temp_offset)* ctl_tree_(tree_temp_offset,tree_temp_multiple, unlink_curr_resume)( ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator )* stack )
00924 {
00925 if( stack->node )
00926 {
00927 ctl_tree_(tree_temp_offset,tree_temp_multiple, _remove )( (ctl_tree(tree_temp_offset,tree_temp_multiple)*)stack->tree, (ctlt_node_type(tree_temp_offset,tree_temp_multiple)*)stack->node );
00928 if( stack->bReverse )
00929 return ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_rbegin_from)( stack, stack->tree, ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, stack->tree,stack->node) );
00930 else
00931 return ctl_tree_(tree_temp_offset,tree_temp_multiple, iterator_begin_from)( stack, stack->tree, ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, stack->tree,stack->node) );
00932 }
00933 return NULL;
00934 }
00935
00936 #ifdef CTL_UNIT
00937 #define CelWidth 2
00938 static void ctl_tree_(tree_temp_offset,tree_temp_multiple, cell_printLines)( ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node, char **buff, size_t coloffset, size_t width )
00939 {
00940 size_t line;
00941 size_t c = coloffset + width;
00942 size_t nLines = (width / 2);
00943 for (line = 1; line <= nLines; ++line)
00944 {
00945
00946 buff[line][1 + c - line] = '/';
00947
00948 buff[line][c + line] = '\\';
00949 }
00950 }
00951
00965 static void ctl_tree_(tree_temp_offset,tree_temp_multiple, cell_print)( const ctl_tree(tree_temp_offset,tree_temp_multiple)* tree, ctlt_node_type(tree_temp_offset,tree_temp_multiple)* node, char **buff, size_t coloffset, size_t width, size_t depth, ctl_tree_printf print, ctlt_node_type(tree_temp_offset,tree_temp_multiple)* nHilight)
00966 {
00967 size_t center = coloffset + (width / 2);
00968 char *pBuff = *buff + center;
00969 if (NULL == node)
00970 {
00971 memcpy (pBuff, "{}", 2);
00972 }
00973 else
00974 {
00975 char tmp[80];
00976 size_t len = print( ctl_tree_node_to_data(tree_temp_offset,tree_temp_multiple, tree,node), tmp, countof (tmp));
00977 len = min (len, width);
00978 pBuff -= -1 + (len / 2) + (nHilight == node) + (0 != node->balance);
00979 if( nHilight == node )
00980 *pBuff++ = '[';
00981 memcpy (pBuff, tmp, len);
00982 pBuff += len;
00983 if( node->balance < 0 )
00984 *pBuff++ = '-';
00985 else if( node->balance > 0 )
00986 *pBuff++ = '+';
00987 if( nHilight == node )
00988 *pBuff++ = ']';
00989
00990 ctl_tree_(tree_temp_offset,tree_temp_multiple, cell_printLines)(node, buff, coloffset, width / 2);
00991 ctl_tree_(tree_temp_offset,tree_temp_multiple, cell_print)(tree, node->left, buff + 1 + width / 4, coloffset, width / 2, depth + 1, print, nHilight);
00992 ctl_tree_(tree_temp_offset,tree_temp_multiple, cell_print)(tree, node->right, buff + 1 + width / 4, center, width / 2, depth + 1, print, nHilight);
00993 }
00994 }
00995
01004 void ctl_tree_(tree_temp_offset,tree_temp_multiple, pretty_print)( const ctl_tree(tree_temp_offset,tree_temp_multiple) *tree, ctl_tree_printf print, ctlt_node_type(tree_temp_offset,tree_temp_multiple)* hilight )
01005 {
01006 size_t maxDepth = ctl_tree_(tree_temp_offset,tree_temp_multiple, depth)(tree);
01007 size_t bottomWidth = 1 << maxDepth;
01008 size_t lineCount = bottomWidth+maxDepth;
01009 char **cells = malloc (lineCount * sizeof (char *));
01010 size_t rowWidth = CelWidth * bottomWidth;
01011 size_t rowCurr;
01012
01013
01014 for (rowCurr = 0; rowCurr < lineCount; ++rowCurr)
01015 {
01016 cells[rowCurr] = malloc (rowWidth + CelWidth + 1);
01017 memset (cells[rowCurr], ' ', rowWidth + CelWidth + 1);
01018 cells[rowCurr][rowWidth + CelWidth] = 0;
01019 }
01020 ctl_tree_(tree_temp_offset,tree_temp_multiple, cell_print)( tree, tree->root, cells, 0, rowWidth, 0, print, hilight );
01021 for (rowCurr = 0; rowCurr < lineCount; ++rowCurr)
01022 {
01023 puts (cells[rowCurr]);
01024 free (cells[rowCurr]);
01025 }
01026 free (cells);
01027 puts ("\n");
01028 }
01029 #endif
01030
01031
01032 #undef tree_fixup
01033 #undef tree_swl
01034 #undef tree_swr
01035 #undef tree_compare
01036 #undef tree_copy
01037 #undef tree_integrate