00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __BINARY_SEARCH_TREE_H
00011 #define __BINARY_SEARCH_TREE_H
00012
00013 #include "DS_QueueLinkedList.h"
00014 #include "RakMemoryOverride.h"
00015 #include "Export.h"
00016
00017
00018 #ifdef _MSC_VER
00019 #pragma warning( push )
00020 #endif
00021
00024 namespace DataStructures
00025 {
00088 template <class BinarySearchTreeType>
00089 class RAK_DLL_EXPORT BinarySearchTree
00090 {
00091
00092 public:
00093
00094 struct node
00095 {
00096 BinarySearchTreeType* item;
00097 node* left;
00098 node* right;
00099 };
00100
00101 BinarySearchTree();
00102 virtual ~BinarySearchTree();
00103 BinarySearchTree( const BinarySearchTree& original_type );
00104 BinarySearchTree& operator= ( const BinarySearchTree& original_copy );
00105 unsigned int Size( void );
00106 void Clear( const char *file, unsigned int line );
00107 unsigned int Height( node* starting_node = 0 );
00108 node* Add ( const BinarySearchTreeType& input, const char *file, unsigned int line );
00109 node* Del( const BinarySearchTreeType& input, const char *file, unsigned int line );
00110 bool IsIn( const BinarySearchTreeType& input );
00111 void DisplayInorder( BinarySearchTreeType* return_array );
00112 void DisplayPreorder( BinarySearchTreeType* return_array );
00113 void DisplayPostorder( BinarySearchTreeType* return_array );
00114 void DisplayBreadthFirstSearch( BinarySearchTreeType* return_array );
00115 BinarySearchTreeType*& GetPointerToNode( const BinarySearchTreeType& element );
00116
00117 protected:
00118
00119 node* root;
00120
00121 enum Direction_Types
00122 {
00123 NOT_FOUND, LEFT, RIGHT, ROOT
00124 } direction;
00125 unsigned int HeightRecursive( node* current );
00126 unsigned int BinarySearchTree_size;
00127 node*& Find( const BinarySearchTreeType& element, node** parent );
00128 node*& FindParent( const BinarySearchTreeType& element );
00129 void DisplayPostorderRecursive( node* current, BinarySearchTreeType* return_array, unsigned int& index );
00130 void FixTree( node* current );
00131
00132 };
00133
00135 template <class BinarySearchTreeType>
00136 class RAK_DLL_EXPORT AVLBalancedBinarySearchTree : public BinarySearchTree<BinarySearchTreeType>
00137 {
00138
00139 public:
00140 AVLBalancedBinarySearchTree() {}
00141 virtual ~AVLBalancedBinarySearchTree();
00142 void Add ( const BinarySearchTreeType& input );
00143 void Del( const BinarySearchTreeType& input );
00144 BinarySearchTree<BinarySearchTreeType>& operator= ( BinarySearchTree<BinarySearchTreeType>& original_copy )
00145 {
00146 return BinarySearchTree<BinarySearchTreeType>::operator= ( original_copy );
00147 }
00148
00149 private:
00150 void BalanceTree( typename BinarySearchTree<BinarySearchTreeType>::node* current, bool rotateOnce );
00151 void RotateRight( typename BinarySearchTree<BinarySearchTreeType>::node *C );
00152 void RotateLeft( typename BinarySearchTree<BinarySearchTreeType>::node* C );
00153 void DoubleRotateRight( typename BinarySearchTree<BinarySearchTreeType>::node *A );
00154 void DoubleRotateLeft( typename BinarySearchTree<BinarySearchTreeType>::node* A );
00155 bool RightHigher( typename BinarySearchTree<BinarySearchTreeType>::node* A );
00156 bool LeftHigher( typename BinarySearchTree<BinarySearchTreeType>::node* A );
00157 };
00158
00159 template <class BinarySearchTreeType>
00160 void AVLBalancedBinarySearchTree<BinarySearchTreeType>::BalanceTree( typename BinarySearchTree<BinarySearchTreeType>::node* current, bool rotateOnce )
00161 {
00162 int left_height, right_height;
00163
00164 while ( current )
00165 {
00166 if ( current->left == 0 )
00167 left_height = 0;
00168 else
00169 left_height = Height( current->left );
00170
00171 if ( current->right == 0 )
00172 right_height = 0;
00173 else
00174 right_height = Height( current->right );
00175
00176 if ( right_height - left_height == 2 )
00177 {
00178 if ( RightHigher( current->right ) )
00179 RotateLeft( current->right );
00180 else
00181 DoubleRotateLeft( current );
00182
00183 if ( rotateOnce )
00184 break;
00185 }
00186
00187 else
00188 if ( right_height - left_height == -2 )
00189 {
00190 if ( LeftHigher( current->left ) )
00191 RotateRight( current->left );
00192 else
00193 DoubleRotateRight( current );
00194
00195 if ( rotateOnce )
00196 break;
00197 }
00198
00199 if ( current == this->root )
00200 break;
00201
00202 current = FindParent( *( current->item ) );
00203
00204 }
00205 }
00206
00207 template <class BinarySearchTreeType>
00208 void AVLBalancedBinarySearchTree<BinarySearchTreeType>::Add ( const BinarySearchTreeType& input )
00209 {
00210
00211 typename BinarySearchTree<BinarySearchTreeType>::node * current = BinarySearchTree<BinarySearchTreeType>::Add ( input, __FILE__,__LINE__ );
00212 BalanceTree( current, true );
00213 }
00214
00215 template <class BinarySearchTreeType>
00216 void AVLBalancedBinarySearchTree<BinarySearchTreeType>::Del( const BinarySearchTreeType& input )
00217 {
00218 typename BinarySearchTree<BinarySearchTreeType>::node * current = BinarySearchTree<BinarySearchTreeType>::Del( input, __FILE__,__LINE__ );
00219 BalanceTree( current, false );
00220
00221 }
00222
00223 template <class BinarySearchTreeType>
00224 bool AVLBalancedBinarySearchTree<BinarySearchTreeType>::RightHigher( typename BinarySearchTree<BinarySearchTreeType>::node *A )
00225 {
00226 if ( A == 0 )
00227 return false;
00228
00229 return Height( A->right ) > Height( A->left );
00230 }
00231
00232 template <class BinarySearchTreeType>
00233 bool AVLBalancedBinarySearchTree<BinarySearchTreeType>::LeftHigher( typename BinarySearchTree<BinarySearchTreeType>::node *A )
00234 {
00235 if ( A == 0 )
00236 return false;
00237
00238 return Height( A->left ) > Height( A->right );
00239 }
00240
00241 template <class BinarySearchTreeType>
00242 void AVLBalancedBinarySearchTree<BinarySearchTreeType>::RotateRight( typename BinarySearchTree<BinarySearchTreeType>::node *C )
00243 {
00244 typename BinarySearchTree<BinarySearchTreeType>::node * A, *B, *D;
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 B = FindParent( *( C->item ) );
00276 A = FindParent( *( B->item ) );
00277 D = C->right;
00278
00279 if ( A )
00280 {
00281
00282
00283 if ( this->direction == this->LEFT )
00284 A->left = C;
00285 else
00286 A->right = C;
00287 }
00288
00289 else
00290 this->root = C;
00291
00292 B->left = D;
00293
00294 C->right = B;
00295 }
00296
00297 template <class BinarySearchTreeType>
00298 void AVLBalancedBinarySearchTree<BinarySearchTreeType>::DoubleRotateRight( typename BinarySearchTree<BinarySearchTreeType>::node *A )
00299 {
00300
00301 RotateLeft( A->left->right );
00302 RotateRight( A->left );
00303 }
00304
00305 template <class BinarySearchTreeType>
00306 void AVLBalancedBinarySearchTree<BinarySearchTreeType>::RotateLeft( typename BinarySearchTree<BinarySearchTreeType>::node *C )
00307 {
00308 typename BinarySearchTree<BinarySearchTreeType>::node * A, *B, *D;
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 B = FindParent( *( C->item ) );
00340 A = FindParent( *( B->item ) );
00341 D = C->left;
00342
00343 if ( A )
00344 {
00345
00346
00347 if ( this->direction == this->LEFT )
00348 A->left = C;
00349 else
00350 A->right = C;
00351 }
00352
00353 else
00354 this->root = C;
00355
00356 B->right = D;
00357
00358 C->left = B;
00359 }
00360
00361 template <class BinarySearchTreeType>
00362 void AVLBalancedBinarySearchTree<BinarySearchTreeType>::DoubleRotateLeft( typename BinarySearchTree<BinarySearchTreeType>::node *A )
00363 {
00364
00365 RotateRight( A->right->left );
00366 RotateLeft( A->right );
00367 }
00368
00369 template <class BinarySearchTreeType>
00370 AVLBalancedBinarySearchTree<BinarySearchTreeType>::~AVLBalancedBinarySearchTree()
00371 {
00372 this->Clear(__FILE__,__LINE__);
00373 }
00374
00375 template <class BinarySearchTreeType>
00376 unsigned int BinarySearchTree<BinarySearchTreeType>::Size( void )
00377 {
00378 return BinarySearchTree_size;
00379 }
00380
00381 template <class BinarySearchTreeType>
00382 unsigned int BinarySearchTree<BinarySearchTreeType>::Height( typename BinarySearchTree::node* starting_node )
00383 {
00384 if ( BinarySearchTree_size == 0 || starting_node == 0 )
00385 return 0;
00386 else
00387 return HeightRecursive( starting_node );
00388 }
00389
00390
00391 template <class BinarySearchTreeType>
00392 unsigned int BinarySearchTree<BinarySearchTreeType>::HeightRecursive( typename BinarySearchTree::node* current )
00393 {
00394 unsigned int left_height = 0, right_height = 0;
00395
00396 if ( ( current->left == 0 ) && ( current->right == 0 ) )
00397 return 1;
00398
00399 if ( current->left != 0 )
00400 left_height = 1 + HeightRecursive( current->left );
00401
00402 if ( current->right != 0 )
00403 right_height = 1 + HeightRecursive( current->right );
00404
00405 if ( left_height > right_height )
00406 return left_height;
00407 else
00408 return right_height;
00409 }
00410
00411 template <class BinarySearchTreeType>
00412 BinarySearchTree<BinarySearchTreeType>::BinarySearchTree()
00413 {
00414 BinarySearchTree_size = 0;
00415 root = 0;
00416 }
00417
00418 template <class BinarySearchTreeType>
00419 BinarySearchTree<BinarySearchTreeType>::~BinarySearchTree()
00420 {
00421 this->Clear(__FILE__,__LINE__);
00422 }
00423
00424 template <class BinarySearchTreeType>
00425 BinarySearchTreeType*& BinarySearchTree<BinarySearchTreeType>::GetPointerToNode( const BinarySearchTreeType& element )
00426 {
00427 static typename BinarySearchTree::node * tempnode;
00428 static BinarySearchTreeType* dummyptr = 0;
00429 tempnode = Find ( element, &tempnode );
00430
00431 if ( this->direction == this->NOT_FOUND )
00432 return dummyptr;
00433
00434 return tempnode->item;
00435 }
00436
00437 template <class BinarySearchTreeType>
00438 typename BinarySearchTree<BinarySearchTreeType>::node*& BinarySearchTree<BinarySearchTreeType>::Find( const BinarySearchTreeType& element, typename BinarySearchTree<BinarySearchTreeType>::node** parent )
00439 {
00440 static typename BinarySearchTree::node * current;
00441
00442 current = this->root;
00443 *parent = 0;
00444 this->direction = this->ROOT;
00445
00446 if ( BinarySearchTree_size == 0 )
00447 {
00448 this->direction = this->NOT_FOUND;
00449 return current = 0;
00450 }
00451
00452
00453 if ( element == *( current->item ) )
00454 {
00455 this->direction = this->ROOT;
00456 return current;
00457 }
00458
00459 #ifdef _MSC_VER
00460 #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
00461 #endif
00462 while ( true )
00463 {
00464
00465
00466 if ( element < *( current->item ) )
00467 {
00468 *parent = current;
00469 this->direction = this->LEFT;
00470 current = current->left;
00471 }
00472
00473 else
00474 if ( element > *( current->item ) )
00475 {
00476 *parent = current;
00477 this->direction = this->RIGHT;
00478 current = current->right;
00479 }
00480
00481 if ( current == 0 )
00482 break;
00483
00484
00485 if ( element == *( current->item ) )
00486 {
00487 return current;
00488 }
00489 }
00490
00491
00492 this->direction = this->NOT_FOUND;
00493 return current = 0;
00494 }
00495
00496 template <class BinarySearchTreeType>
00497 typename BinarySearchTree<BinarySearchTreeType>::node*& BinarySearchTree<BinarySearchTreeType>::FindParent( const BinarySearchTreeType& element )
00498 {
00499 static typename BinarySearchTree::node * parent;
00500 Find ( element, &parent );
00501 return parent;
00502 }
00503
00504
00505 template <class BinarySearchTreeType>
00506 void BinarySearchTree<BinarySearchTreeType>::FixTree( typename BinarySearchTree::node* current )
00507 {
00508 BinarySearchTreeType temp;
00509
00510 while ( 1 )
00511 {
00512 if ( ( ( current->left ) != 0 ) && ( *( current->item ) < *( current->left->item ) ) )
00513 {
00514
00515 temp = *( current->left->item );
00516 *( current->left->item ) = *( current->item );
00517 *( current->item ) = temp;
00518 current = current->left;
00519 }
00520
00521 else
00522 if ( ( ( current->right ) != 0 ) && ( *( current->item ) > *( current->right->item ) ) )
00523 {
00524
00525 temp = *( current->right->item );
00526 *( current->right->item ) = *( current->item );
00527 *( current->item ) = temp;
00528 current = current->right;
00529 }
00530
00531 else
00532 break;
00533 }
00534 }
00535
00536 template <class BinarySearchTreeType>
00537 typename BinarySearchTree<BinarySearchTreeType>::node* BinarySearchTree<BinarySearchTreeType>::Del( const BinarySearchTreeType& input, const char *file, unsigned int line )
00538 {
00539 typename BinarySearchTree::node * node_to_delete, *current, *parent;
00540
00541 if ( BinarySearchTree_size == 0 )
00542 return 0;
00543
00544 if ( BinarySearchTree_size == 1 )
00545 {
00546 Clear(file, line);
00547 return 0;
00548 }
00549
00550 node_to_delete = Find( input, &parent );
00551
00552 if ( direction == NOT_FOUND )
00553 return 0;
00554
00555 current = node_to_delete;
00556
00557
00558 if ( ( current->right ) == 0 && ( current->left ) == 0 )
00559 {
00560
00561 if ( parent )
00562 {
00563 if ( direction == LEFT )
00564 parent->left = 0;
00565 else
00566 parent->right = 0;
00567 }
00568
00569 RakNet::OP_DELETE(node_to_delete->item, file, line);
00570 RakNet::OP_DELETE(node_to_delete, file, line);
00571 BinarySearchTree_size--;
00572 return parent;
00573 }
00574 else
00575 if ( ( current->right ) != 0 && ( current->left ) == 0 )
00576 {
00577
00578 if ( parent )
00579 {
00580 if ( direction == RIGHT )
00581 parent->right = current->right;
00582 else
00583 parent->left = current->right;
00584 }
00585
00586 else
00587 root = current->right;
00588
00589 RakNet::OP_DELETE(node_to_delete->item, file, line);
00590
00591 RakNet::OP_DELETE(node_to_delete, file, line);
00592
00593 BinarySearchTree_size--;
00594
00595 return parent;
00596 }
00597 else
00598 if ( ( current->right ) == 0 && ( current->left ) != 0 )
00599 {
00600
00601 if ( parent )
00602 {
00603 if ( direction == RIGHT )
00604 parent->right = current->left;
00605 else
00606 parent->left = current->left;
00607 }
00608
00609 else
00610 root = current->left;
00611
00612 RakNet::OP_DELETE(node_to_delete->item, file, line);
00613
00614 RakNet::OP_DELETE(node_to_delete, file, line);
00615
00616 BinarySearchTree_size--;
00617
00618 return parent;
00619 }
00620 else
00621 {
00622 parent = current;
00623 direction = RIGHT;
00624 current = current->right;
00625
00626 while ( current->left )
00627 {
00628 direction = LEFT;
00629 parent = current;
00630 current = current->left;
00631 }
00632
00633
00634 *( node_to_delete->item ) = *( current->item );
00635
00636
00637
00638 if ( current->right == 0 )
00639 {
00640 if ( direction == RIGHT )
00641 parent->right = 0;
00642 else
00643 parent->left = 0;
00644
00645 RakNet::OP_DELETE(current->item, file, line);
00646
00647 RakNet::OP_DELETE(current, file, line);
00648
00649 BinarySearchTree_size--;
00650
00651 return parent;
00652 }
00653
00654 else
00655 {
00656
00657
00658 if ( direction == RIGHT )
00659 parent->right = current->right;
00660 else
00661 parent->left = current->right;
00662
00663 RakNet::OP_DELETE(current->item, file, line);
00664
00665 RakNet::OP_DELETE(current, file, line);
00666
00667 BinarySearchTree_size--;
00668
00669 return parent;
00670 }
00671 }
00672 }
00673
00674 template <class BinarySearchTreeType>
00675 typename BinarySearchTree<BinarySearchTreeType>::node* BinarySearchTree<BinarySearchTreeType>::Add ( const BinarySearchTreeType& input, const char *file, unsigned int line )
00676 {
00677 typename BinarySearchTree::node * current;
00678
00679
00680
00681
00682
00683
00684 if ( BinarySearchTree_size == 0 )
00685 {
00686 BinarySearchTree_size = 1;
00687 root = RakNet::OP_NEW<typename BinarySearchTree::node>( file, line );
00688 root->item = RakNet::OP_NEW<BinarySearchTreeType>( file, line );
00689 *( root->item ) = input;
00690 root->left = 0;
00691 root->right = 0;
00692
00693 return root;
00694 }
00695
00696 else
00697 {
00698
00699 current = root;
00700
00701 #ifdef _MSC_VER
00702 #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
00703 #endif
00704 while ( true )
00705 {
00706
00707 if ( input < *( current->item ) )
00708 {
00709 if ( current->left == 0 )
00710 {
00711 current->left = RakNet::OP_NEW<typename BinarySearchTree::node>( file, line );
00712 current->left->item = RakNet::OP_NEW<BinarySearchTreeType>( file, line );
00713 current = current->left;
00714 current->left = 0;
00715 current->right = 0;
00716 *( current->item ) = input;
00717
00718 BinarySearchTree_size++;
00719 return current;
00720 }
00721
00722 else
00723 {
00724 current = current->left;
00725 }
00726 }
00727
00728 else
00729 if ( input > *( current->item ) )
00730 {
00731 if ( current->right == 0 )
00732 {
00733 current->right = RakNet::OP_NEW<typename BinarySearchTree::node>( file, line );
00734 current->right->item = RakNet::OP_NEW<BinarySearchTreeType>( file, line );
00735 current = current->right;
00736 current->left = 0;
00737 current->right = 0;
00738 *( current->item ) = input;
00739
00740 BinarySearchTree_size++;
00741 return current;
00742 }
00743
00744 else
00745 {
00746 current = current->right;
00747 }
00748 }
00749
00750 else
00751 return 0;
00752 }
00753 }
00754 }
00755
00756 template <class BinarySearchTreeType>
00757 bool BinarySearchTree<BinarySearchTreeType>::IsIn( const BinarySearchTreeType& input )
00758 {
00759 typename BinarySearchTree::node * parent;
00760 find( input, &parent );
00761
00762 if ( direction != NOT_FOUND )
00763 return true;
00764 else
00765 return false;
00766 }
00767
00768
00769 template <class BinarySearchTreeType>
00770 void BinarySearchTree<BinarySearchTreeType>::DisplayInorder( BinarySearchTreeType* return_array )
00771 {
00772 typename BinarySearchTree::node * current, *parent;
00773 bool just_printed = false;
00774
00775 unsigned int index = 0;
00776
00777 current = root;
00778
00779 if ( BinarySearchTree_size == 0 )
00780 return ;
00781
00782 else
00783 if ( BinarySearchTree_size == 1 )
00784 {
00785 return_array[ 0 ] = *( root->item );
00786 return ;
00787 }
00788
00789
00790 direction = ROOT;
00791
00792 while ( index != BinarySearchTree_size )
00793 {
00794
00795
00796 if ( ( current->left != 0 ) && ( direction != LEFT ) && ( direction != RIGHT ) )
00797 {
00798
00799
00800
00801
00802
00803 current = current->left;
00804 direction = ROOT;
00805 }
00806
00807 else
00808 if ( ( direction != RIGHT ) && ( just_printed == false ) )
00809 {
00810
00811
00812
00813
00814 return_array[ index++ ] = *( current->item );
00815 just_printed = true;
00816 }
00817
00818 else
00819 if ( ( current->right != 0 ) && ( direction != RIGHT ) )
00820 {
00821
00822
00823
00824
00825 current = current->right;
00826 direction = ROOT;
00827 just_printed = false;
00828 }
00829
00830 else
00831 {
00832
00833 parent = FindParent( *( current->item ) );
00834 current = parent;
00835 just_printed = false;
00836 }
00837 }
00838 }
00839
00840 template <class BinarySearchTreeType>
00841 void BinarySearchTree<BinarySearchTreeType>::DisplayPreorder( BinarySearchTreeType* return_array )
00842 {
00843 typename BinarySearchTree::node * current, *parent;
00844
00845 unsigned int index = 0;
00846
00847 current = root;
00848
00849 if ( BinarySearchTree_size == 0 )
00850 return ;
00851
00852 else
00853 if ( BinarySearchTree_size == 1 )
00854 {
00855 return_array[ 0 ] = *( root->item );
00856 return ;
00857 }
00858
00859
00860 direction = ROOT;
00861 return_array[ index++ ] = *( current->item );
00862
00863 while ( index != BinarySearchTree_size )
00864 {
00865
00866
00867 if ( ( current->left != 0 ) && ( direction != LEFT ) && ( direction != RIGHT ) )
00868 {
00869
00870 current = current->left;
00871 direction = ROOT;
00872
00873
00874 return_array[ index++ ] = *( current->item );
00875 }
00876
00877 else
00878 if ( ( current->right != 0 ) && ( direction != RIGHT ) )
00879 {
00880 current = current->right;
00881 direction = ROOT;
00882
00883
00884 return_array[ index++ ] = *( current->item );
00885 }
00886
00887 else
00888 {
00889
00890 parent = FindParent( *( current->item ) );
00891 current = parent;
00892 }
00893 }
00894 }
00895
00896 template <class BinarySearchTreeType>
00897 inline void BinarySearchTree<BinarySearchTreeType>::DisplayPostorder( BinarySearchTreeType* return_array )
00898 {
00899 unsigned int index = 0;
00900
00901 if ( BinarySearchTree_size == 0 )
00902 return ;
00903
00904 else
00905 if ( BinarySearchTree_size == 1 )
00906 {
00907 return_array[ 0 ] = *( root->item );
00908 return ;
00909 }
00910
00911 DisplayPostorderRecursive( root, return_array, index );
00912 }
00913
00914
00915
00916 template <class BinarySearchTreeType>
00917 void BinarySearchTree<BinarySearchTreeType>::DisplayPostorderRecursive( typename BinarySearchTree::node* current, BinarySearchTreeType* return_array, unsigned int& index )
00918 {
00919 if ( current->left != 0 )
00920 DisplayPostorderRecursive( current->left, return_array, index );
00921
00922 if ( current->right != 0 )
00923 DisplayPostorderRecursive( current->right, return_array, index );
00924
00925 return_array[ index++ ] = *( current->item );
00926
00927 }
00928
00929
00930 template <class BinarySearchTreeType>
00931 void BinarySearchTree<BinarySearchTreeType>::DisplayBreadthFirstSearch( BinarySearchTreeType* return_array )
00932 {
00933 typename BinarySearchTree::node * current;
00934 unsigned int index = 0;
00935
00936
00937
00938
00939
00940 if ( BinarySearchTree_size == 0 )
00941 return ;
00942
00943 else
00944 if ( BinarySearchTree_size == 1 )
00945 {
00946 return_array[ 0 ] = *( root->item );
00947 return ;
00948 }
00949
00950 else
00951 {
00952 DataStructures::QueueLinkedList<node *> tree_queue;
00953
00954
00955 tree_queue.Push( root );
00956
00957 do
00958 {
00959 current = tree_queue.Pop();
00960 return_array[ index++ ] = *( current->item );
00961
00962
00963
00964 if ( current->left != 0 )
00965 tree_queue.Push( current->left );
00966
00967 if ( current->right != 0 )
00968 tree_queue.Push( current->right );
00969
00970 }
00971
00972 while ( tree_queue.Size() > 0 );
00973 }
00974 }
00975
00976
00977 template <class BinarySearchTreeType>
00978 BinarySearchTree<BinarySearchTreeType>::BinarySearchTree( const BinarySearchTree& original_copy )
00979 {
00980 typename BinarySearchTree::node * current;
00981
00982
00983
00984
00985
00986 BinarySearchTree_size = 0;
00987 root = 0;
00988
00989 if ( original_copy.BinarySearchTree_size == 0 )
00990 {
00991 BinarySearchTree_size = 0;
00992 }
00993
00994 else
00995 {
00996 DataStructures::QueueLinkedList<node *> tree_queue;
00997
00998
00999 tree_queue.Push( original_copy.root );
01000
01001 do
01002 {
01003 current = tree_queue.Pop();
01004
01005 Add ( *( current->item ), __FILE__, __LINE__ )
01006
01007 ;
01008
01009
01010 if ( current->left != 0 )
01011 tree_queue.Push( current->left );
01012
01013 if ( current->right != 0 )
01014 tree_queue.Push( current->right );
01015
01016 }
01017
01018 while ( tree_queue.Size() > 0 );
01019 }
01020 }
01021
01022 template <class BinarySearchTreeType>
01023 BinarySearchTree<BinarySearchTreeType>& BinarySearchTree<BinarySearchTreeType>::operator= ( const BinarySearchTree& original_copy )
01024 {
01025 typename BinarySearchTree::node * current;
01026
01027 if ( ( &original_copy ) == this )
01028 return *this;
01029
01030 Clear( __FILE__, __LINE__ );
01031
01032
01033 BinarySearchTree_size = 0;
01034
01035 root = 0;
01036
01037
01038
01039
01040
01041 if ( original_copy.BinarySearchTree_size == 0 )
01042 {
01043 BinarySearchTree_size = 0;
01044 }
01045
01046 else
01047 {
01048 DataStructures::QueueLinkedList<node *> tree_queue;
01049
01050
01051 tree_queue.Push( original_copy.root );
01052
01053 do
01054 {
01055 current = tree_queue.Pop();
01056
01057 Add ( *( current->item ), __FILE__, __LINE__ )
01058
01059 ;
01060
01061
01062 if ( current->left != 0 )
01063 tree_queue.Push( current->left );
01064
01065 if ( current->right != 0 )
01066 tree_queue.Push( current->right );
01067
01068 }
01069
01070 while ( tree_queue.Size() > 0 );
01071 }
01072
01073 return *this;
01074 }
01075
01076 template <class BinarySearchTreeType>
01077 inline void BinarySearchTree<BinarySearchTreeType>::Clear ( const char *file, unsigned int line )
01078 {
01079 typename BinarySearchTree::node * current, *parent;
01080
01081 current = root;
01082
01083 while ( BinarySearchTree_size > 0 )
01084 {
01085 if ( BinarySearchTree_size == 1 )
01086 {
01087 RakNet::OP_DELETE(root->item, file, line);
01088 RakNet::OP_DELETE(root, file, line);
01089 root = 0;
01090 BinarySearchTree_size = 0;
01091 }
01092
01093 else
01094 {
01095 if ( current->left != 0 )
01096 {
01097 current = current->left;
01098 }
01099
01100 else
01101 if ( current->right != 0 )
01102 {
01103 current = current->right;
01104 }
01105
01106 else
01107 {
01108
01109 parent = FindParent( *( current->item ) );
01110
01111 if ( ( parent->left ) == current )
01112 parent->left = 0;
01113 else
01114 parent->right = 0;
01115
01116 RakNet::OP_DELETE(current->item, file, line);
01117
01118 RakNet::OP_DELETE(current, file, line);
01119
01120 current = parent;
01121
01122 BinarySearchTree_size--;
01123 }
01124 }
01125 }
01126 }
01127
01128 }
01129
01130 #endif
01131
01132 #ifdef _MSC_VER
01133 #pragma warning( pop )
01134 #endif