include/gn/IntervalSequenceTree.h

Go to the documentation of this file.
00001 #ifndef __IntervalSequenceTree_h__ 00002 #define __IntervalSequenceTree_h__ 00003 00004 #include <vector> 00005 00006 /* 00007 class interval { 00008 gnSeqI length(); 00009 cropEnd(); 00010 cropStart(); 00011 } 00012 */ 00013 00014 // select idea shamelessly ripped from Metrowerks 00015 template <bool Condition, class If, class Then> 00016 class type_select 00017 { 00018 public: 00019 typedef If type; 00020 }; 00021 00022 template <class If, class Then> 00023 class type_select<false, If, Then> 00024 { 00025 public: 00026 typedef Then type; 00027 }; 00028 00029 static const uint64 IST_END = ((0xFFFFFFFF << 31) << 1 ) + 0xFFFFFFFF; 00030 00040 template< class Key, class Allocator = allocator<Key> > 00041 class IntervalSequenceTree 00042 { 00043 public: 00044 typedef Key value_type; 00045 // typedef unsigned long long size_type; 00046 00047 typedef Allocator allocator_type; 00048 typedef typename Allocator::reference reference; 00049 typedef typename Allocator::const_reference const_reference; 00050 typedef typename Allocator::size_type size_type; 00051 typedef typename Allocator::difference_type difference_type; 00052 typedef typename Allocator::pointer pointer; 00053 typedef typename Allocator::const_pointer const_pointer; 00054 00055 // node types and iterator definitions 00056 protected: 00065 class IstNode { 00066 public: 00067 IstNode* parent; 00068 IstNode* left; 00069 IstNode* right; 00070 size_type subtree_size; 00071 size_type length; 00072 Key* key; 00073 00074 IstNode() : 00075 parent( NULL ), 00076 left( NULL ), 00077 right( NULL ), 00078 subtree_size( 0 ), 00079 length( 0 ), 00080 key( NULL ) {} 00081 }; 00082 typedef typename Allocator::template rebind<IstNode>::other node_allocator_type; 00083 // typedef typename allocator_type::rebind<IstNode>::other node_allocator_type; 00084 typedef typename node_allocator_type::pointer node_pointer; 00085 typedef typename node_allocator_type::const_pointer const_node_pointer; 00086 00087 // typedef typename IstNode* node_pointer; 00088 // typedef typename const IstNode* const_node_pointer; 00089 00090 public: 00091 00092 // generic bidirectional iterator interface ripped from MSL, thanks guys 00093 template <bool is_const> 00094 class __generic_iterator 00095 { 00096 public: 00097 typedef typename IntervalSequenceTree::value_type value_type; 00098 // typedef typename IntervalSequenceTree::difference_type difference_type; 00099 typedef typename type_select<is_const, typename IntervalSequenceTree::const_pointer, 00100 typename IntervalSequenceTree::pointer>::type pointer; 00101 typedef typename type_select<is_const, typename IntervalSequenceTree::const_reference, 00102 typename IntervalSequenceTree::reference>::type reference; 00103 typedef bidirectional_iterator_tag iterator_category; 00104 00105 __generic_iterator() {} 00106 __generic_iterator(const __generic_iterator<false>& i) : ptr_(i.ptr_) {} 00107 reference operator * () const {return ptr_->data_;} 00108 pointer operator -> () const {return &ptr_->data_;} 00109 __generic_iterator& operator ++ () {increment((const IstNode*&)ptr_); return *this;} 00110 __generic_iterator operator ++ (int) {__generic_iterator tmp(*this); ++(*this); return tmp;} 00111 __generic_iterator& operator -- () {decrement((const IstNode*&)ptr_); return *this;} 00112 __generic_iterator operator -- (int) {__generic_iterator tmp(*this); --(*this); return tmp;} 00113 friend bool operator ==(const __generic_iterator& x, const __generic_iterator& y) {return x.ptr_ == y.ptr_;} 00114 friend bool operator !=(const __generic_iterator& x, const __generic_iterator& y) {return x.ptr_ != y.ptr_;} 00115 private: 00116 typedef typename type_select<is_const, typename IntervalSequenceTree::node_pointer, 00117 typename IntervalSequenceTree::const_node_pointer>::type node_pointer; 00118 00119 node_pointer ptr_; 00120 00121 explicit __generic_iterator(node_pointer n) : ptr_(n) {} 00122 00123 friend class __generic_iterator<true>; 00124 friend class IntervalSequenceTree; 00125 }; 00126 00127 friend class __generic_iterator<false>; 00128 friend class __generic_iterator<true>; 00129 typedef __generic_iterator<false> iterator; 00130 typedef __generic_iterator<true> const_iterator; 00131 typedef std::reverse_iterator< iterator > reverse_iterator; 00132 typedef std::reverse_iterator< const_iterator > const_reverse_iterator; 00133 00134 00135 // constructor related methods 00136 IntervalSequenceTree(); 00137 template< class InputIterator > 00138 IntervalSequenceTree( InputIterator first, InputIterator last ); 00139 IntervalSequenceTree( const IntervalSequenceTree& ist ); 00140 IntervalSequenceTree& operator=( const IntervalSequenceTree& ist ); 00141 ~IntervalSequenceTree(); 00142 00143 // standard container methods 00144 iterator begin(); 00145 const_iterator begin() const; 00146 iterator end(); 00147 const_iterator end() const; 00148 reverse_iterator rbegin(); 00149 const_reverse_iterator rbegin() const; 00150 reverse_iterator rend(); 00151 const_reverse_iterator rend() const; 00152 size_type max_size() const; 00153 bool empty() const; 00154 00155 // insertion and erasure 00156 iterator insert( const value_type& val, size_type point = IST_END ); 00157 template <class InputIterator> 00158 void insert(InputIterator first, InputIterator last, size_type point = IST_END ); 00159 00160 size_type erase( size_type point, size_type length ); 00161 void erase( iterator first, iterator last ); 00162 00163 // search 00164 iterator find( size_type point ); 00165 const_iterator find( size_type point ) const; 00166 00167 // interval sequence specific: 00171 size_type length() const; 00172 size_type nodeCount() const; 00173 size_type countNodes( IstNode* x = NULL ) const; 00174 00175 protected: 00176 IstNode *root; 00177 IstNode *leftmost; 00178 IstNode *rightmost; 00180 static void propogateChanges( IstNode* cur_node, int64 length_diff, int64 subtree_diff ); 00181 static IstNode* recursiveFind( size_type& point, IstNode* node ); 00182 static void increment( IstNode*& x); 00183 void decrement( IstNode*& x) const; 00184 static void deleteSubtree( IstNode*& istn ); 00185 static void checkTree( IstNode* cur_node ); 00186 }; 00187 00188 00189 00190 //template< class Key, class Allocator > 00191 //IntervalSequenceTree< Key, Allocator >::IST_END = -1; 00192 00193 template< class Key, class Allocator > 00194 inline 00195 IntervalSequenceTree< Key, Allocator >::IntervalSequenceTree(){ 00196 root = NULL; 00197 leftmost = NULL; 00198 rightmost = NULL; 00199 // IST_END = -1; // wraps to UINT64_MAX because IST_END is unsigned 00200 } 00201 00202 template< class Key, class Allocator > 00203 template< class InputIterator > 00204 IntervalSequenceTree< Key, Allocator >::IntervalSequenceTree( InputIterator first, InputIterator last ){ 00205 insert( first, last ); 00206 } 00207 00208 template< class Key, class Allocator > 00209 IntervalSequenceTree< Key, Allocator >::IntervalSequenceTree( const IntervalSequenceTree& ist ){ 00210 insert( ist.begin(), ist.end() ); 00211 } 00212 00213 template< class Key, class Allocator > 00214 IntervalSequenceTree< Key, Allocator >& IntervalSequenceTree< Key, Allocator >::operator=( const IntervalSequenceTree& ist ){ 00215 insert( ist.begin(), ist.end() ); 00216 } 00217 00218 template< class Key, class Allocator > 00219 IntervalSequenceTree< Key, Allocator >::~IntervalSequenceTree(){ 00220 deleteSubtree( root ); 00221 } 00222 00223 template< class Key, class Allocator > 00224 typename IntervalSequenceTree< Key, Allocator >::iterator 00225 IntervalSequenceTree< Key, Allocator >::begin(){ 00226 return iterator( leftmost ); 00227 } 00228 00229 template< class Key, class Allocator > 00230 typename IntervalSequenceTree< Key, Allocator >::const_iterator 00231 IntervalSequenceTree< Key, Allocator >::begin() const{ 00232 return const_iterator( leftmost ); 00233 } 00234 00235 template< class Key, class Allocator > 00236 typename IntervalSequenceTree< Key, Allocator >::iterator 00237 IntervalSequenceTree< Key, Allocator >::end(){ 00238 return iterator( NULL ); 00239 } 00240 00241 template< class Key, class Allocator > 00242 typename IntervalSequenceTree< Key, Allocator >::const_iterator 00243 IntervalSequenceTree< Key, Allocator >::end() const{ 00244 return const_iterator( NULL ); 00245 } 00246 00247 template< class Key, class Allocator > 00248 typename IntervalSequenceTree< Key, Allocator >::reverse_iterator 00249 IntervalSequenceTree< Key, Allocator >::rbegin(){ 00250 return reverse_iterator( end() ); 00251 } 00252 00253 template< class Key, class Allocator > 00254 typename IntervalSequenceTree< Key, Allocator >::const_reverse_iterator 00255 IntervalSequenceTree< Key, Allocator >::rbegin() const{ 00256 return const_reverse_iterator( end() ); 00257 } 00258 00259 template< class Key, class Allocator > 00260 typename IntervalSequenceTree< Key, Allocator >::reverse_iterator 00261 IntervalSequenceTree< Key, Allocator >::rend(){ 00262 return reverse_iterator( begin() ); 00263 } 00264 00265 template< class Key, class Allocator > 00266 typename IntervalSequenceTree< Key, Allocator >::const_reverse_iterator 00267 IntervalSequenceTree< Key, Allocator >::rend() const{ 00268 return const_reverse_iterator( begin() ); 00269 } 00270 00271 template< class Key, class Allocator > 00272 typename IntervalSequenceTree< Key, Allocator >::size_type 00273 IntervalSequenceTree< Key, Allocator >::max_size() const{ 00274 return IST_END - 1; 00275 } 00276 00277 template< class Key, class Allocator > 00278 bool IntervalSequenceTree< Key, Allocator >::empty() const{ 00279 return root == NULL ? true : false; 00280 } 00281 00282 template< class Key, class Allocator > 00283 void IntervalSequenceTree< Key, Allocator >::checkTree( 00284 IntervalSequenceTree< Key, Allocator >::IstNode* cur_node ){ 00285 if( cur_node ){ 00286 if( cur_node->parent == cur_node ) 00287 cerr << "freakout\n"; 00288 checkTree( cur_node->left ); 00289 checkTree( cur_node->right ); 00290 } 00291 } 00292 00293 template< class Key, class Allocator > 00294 typename IntervalSequenceTree< Key, Allocator >::iterator 00295 IntervalSequenceTree< Key, Allocator >::insert( 00296 const Key& val, 00297 IntervalSequenceTree< Key, Allocator >::size_type point ) 00298 { 00299 size_type iv_offset = point; 00300 IstNode* ins_node = recursiveFind( iv_offset, root ); 00301 IstNode* new_node = new IstNode(); 00302 new_node->key = new Key( val ); 00303 new_node->length = val.GetLength(); 00304 new_node->subtree_size = 0; 00305 if( ins_node == NULL ){ 00306 // end insert 00307 rightmost = new_node; 00308 if( root == NULL ){ 00309 root = new_node; 00310 leftmost = new_node; 00311 return iterator( new_node ); 00312 } 00313 // find the shallowest right insertion point 00314 ins_node = NULL; 00315 decrement( ins_node ); 00316 // make a new parent node 00317 IstNode* new_parent = new IstNode(); 00318 new_parent->left = ins_node; 00319 new_parent->right = new_node; 00320 new_parent->parent = ins_node->parent; 00321 if( new_parent->parent == NULL ) 00322 root = new_parent; 00323 else 00324 new_parent->parent->right = new_parent; 00325 ins_node->parent = new_parent; 00326 new_parent->length = ins_node->length; 00327 00328 // update lengths and subtree_sizes along the path to the root 00329 // checkTree( root ); 00330 // propogateChanges( new_node, 0, 0 ); 00331 // propogateChanges( ins_node, 0, 0 ); 00332 propogateChanges( new_parent, new_node->length, 2 ); 00333 return iterator( new_node ); 00334 } 00335 00336 // iv_offset is the distance into the node that the leaf should be split 00337 // 0 is a special case (left insert) 00338 if( iv_offset == 0 ){ 00339 IstNode* new_parent = new IstNode(); 00340 new_parent->left = new_node; 00341 new_parent->right = ins_node; 00342 new_parent->parent = ins_node->parent; 00343 if( new_parent->parent->right == ins_node ) 00344 new_parent->parent->right = new_parent; 00345 else 00346 new_parent->parent->left = new_parent; 00347 new_parent->length = ins_node->length; 00348 00349 ins_node->parent = new_parent; 00350 new_node->parent = new_parent; 00351 00352 if( point == 0 ) 00353 leftmost = new_node; 00354 // update lengths and subtree_sizes along the path to the root 00355 // checkTree( root ); 00356 // propogateChanges( new_node, 0, 0 ); 00357 // propogateChanges( ins_node, 0, 0 ); 00358 propogateChanges( new_parent, new_node->length, 2 ); 00359 }else{ 00360 // need to split a leaf node 00361 IstNode* new_gp = new IstNode(); 00362 IstNode* new_parent = new IstNode(); 00363 new_gp->parent = ins_node->parent; 00364 new_gp->right = new_parent; 00365 new_gp->left = new IstNode(); 00366 new_gp->left->key = new Key( *ins_node->key ); 00367 new_gp->left->key->CropEnd( ins_node->length - iv_offset ); 00368 new_gp->left->length = new_gp->left->key->GetLength(); 00369 new_gp->left->parent = new_gp; 00370 00371 ins_node->key->CropStart( iv_offset ); 00372 ins_node->length = ins_node->key->GetLength(); 00373 ins_node->parent = new_parent; 00374 new_node->parent = new_parent; 00375 new_parent->left = new_node; 00376 new_parent->right = ins_node; 00377 new_parent->parent = new_gp; 00378 new_parent->length = new_node->length + ins_node->length; 00379 new_parent->subtree_size = 2; 00380 00381 new_gp->length = ins_node->length + new_gp->left->length; 00382 new_gp->subtree_size = 1; 00383 if( new_gp->parent == NULL ){ 00384 root = new_gp; 00385 leftmost = new_gp->left; 00386 rightmost = ins_node; 00387 }else if( new_gp->parent->right == ins_node ) 00388 new_gp->parent->right = new_gp; 00389 else 00390 new_gp->parent->left = new_gp; 00391 00392 // update lengths and subtree_sizes along the path to the root 00393 // checkTree( root ); 00394 // propogateChanges( new_node, 0, 0 ); 00395 // propogateChanges( ins_node, 0, 0 ); 00396 // propogateChanges( new_gp->left, 0, 0 ); 00397 // propogateChanges( new_parent, 0, 0 ); 00398 new_gp->subtree_size = -1; 00399 propogateChanges( new_gp, new_node->length, 4 ); 00400 } 00401 return iterator( new_node ); 00402 } 00403 00404 template< class Key, class Allocator > 00405 template <class InputIterator> 00406 void IntervalSequenceTree< Key, Allocator >::insert( 00407 InputIterator first, 00408 InputIterator last, 00409 IntervalSequenceTree< Key, Allocator >::size_type point ) 00410 { 00411 00412 } 00413 00414 template< class Key, class Allocator > 00415 typename IntervalSequenceTree< Key, Allocator >::size_type 00416 IntervalSequenceTree< Key, Allocator >::erase( 00417 IntervalSequenceTree< Key, Allocator >::size_type point, 00418 IntervalSequenceTree< Key, Allocator >::size_type length ) 00419 { 00420 size_type iv_offset = point; 00421 IstNode* ins_node = recursiveFind( iv_offset, root ); 00422 00423 // iv_offset is the distance into the node that the leaf should be split 00424 // 0 is a special case (left delete) 00425 size_type deleted_nodes = 0; 00426 while( length > 0 ){ 00427 if( ins_node == NULL ){ 00428 // end delete? that's illegal 00429 return deleted_nodes; 00430 } 00431 if( iv_offset == 0 ){ 00432 if( length >= ins_node->length ){ 00433 // delete the whole thing 00434 length -= ins_node->length; 00435 if( ins_node->parent == NULL ){ 00436 // deleting the root 00437 delete ins_node; 00438 root = NULL; 00439 leftmost = NULL; 00440 rightmost = NULL; 00441 return deleted_nodes + 1; 00442 } 00443 00444 IstNode* other_child, *del_node; 00445 if( ins_node->parent->left == ins_node ){ 00446 other_child = ins_node->parent->right; 00447 }else if( ins_node->parent->right == ins_node ){ 00448 other_child = ins_node->parent->left; 00449 } 00450 del_node = ins_node; 00451 increment( ins_node ); 00452 00453 // update tree structure 00454 IstNode* tmp_parent = other_child->parent; 00455 IstNode* tmp_gp = tmp_parent->parent; 00456 *tmp_parent = *other_child; 00457 tmp_parent->parent = tmp_gp; 00458 if( tmp_parent->left ) 00459 tmp_parent->left->parent = tmp_parent; 00460 if( tmp_parent->right ) 00461 tmp_parent->right->parent = tmp_parent; 00462 if( ins_node == other_child ) 00463 ins_node = tmp_parent; 00464 delete other_child; 00465 00466 // propogate deletion length thru root 00467 tmp_parent = tmp_parent->parent; 00468 // checkTree( root ); 00469 propogateChanges( tmp_parent, -del_node->length, -2 ); 00470 00471 // finally delete ins_node 00472 delete del_node; 00473 ++deleted_nodes; 00474 }else{ 00475 // crop from start 00476 ins_node->key->CropStart( length ); 00477 // checkTree( root ); 00478 propogateChanges( ins_node, -length, 0 ); 00479 return deleted_nodes; 00480 } 00481 }else if( length >= ins_node->length - iv_offset ){ 00482 // crop from end 00483 ins_node->key->CropEnd( ins_node->length - iv_offset ); 00484 length -= ins_node->length - iv_offset; 00485 // checkTree( root ); 00486 propogateChanges( ins_node, -(ins_node->length - iv_offset), 0 ); 00487 increment( ins_node ); 00488 iv_offset = 0; 00489 }else{ 00490 // delete from middle (nastee part) 00491 IstNode* new_parent = new IstNode(); 00492 new_parent->left = ins_node; 00493 new_parent->length = ins_node->length; 00494 new_parent->right = new IstNode(); 00495 new_parent->right->key = new Key( *ins_node->key ); 00496 new_parent->right->length = ins_node->length - length - iv_offset; 00497 new_parent->right->key->CropStart( length + iv_offset ); 00498 new_parent->left->key->CropEnd( ins_node->length - iv_offset ); 00499 new_parent->left->length = iv_offset; 00500 new_parent->parent = ins_node->parent; 00501 if( new_parent->parent == NULL ){ 00502 root = new_parent; 00503 rightmost = new_parent->right; 00504 }else if( new_parent->parent->left == ins_node ) 00505 new_parent->parent->left = new_parent; 00506 else if( new_parent->parent->right == ins_node ) 00507 new_parent->parent->right = new_parent; 00508 00509 ins_node->parent = new_parent; 00510 new_parent->right->parent = new_parent; 00511 // checkTree( root ); 00512 // propogateChanges( ins_node, 0, 0 ); 00513 // propogateChanges( new_parent->right, 0, 0 ); 00514 propogateChanges( new_parent, -length, 2 ); 00515 return deleted_nodes; 00516 } 00517 } 00518 return deleted_nodes; 00519 } 00520 00521 template< class Key, class Allocator > 00522 void IntervalSequenceTree< Key, Allocator >::propogateChanges( 00523 IstNode* cur_node, 00524 int64 length_diff, 00525 int64 subtree_diff ) 00526 { 00527 vector< IstNode* > node_stack; 00528 while( cur_node != NULL ){ 00529 if( cur_node->parent == cur_node ) 00530 cerr << "when I say oh, you say shit!"; 00531 cur_node->length += length_diff; 00532 cur_node->subtree_size += subtree_diff; 00533 node_stack.push_back( cur_node ); 00534 cur_node = cur_node->parent; 00535 } 00536 } 00537 00538 template< class Key, class Allocator > 00539 void IntervalSequenceTree< Key, Allocator >::erase( 00540 IntervalSequenceTree< Key, Allocator >::iterator first, 00541 IntervalSequenceTree< Key, Allocator >::iterator last ) 00542 { 00543 00544 } 00545 00546 template< class Key, class Allocator > 00547 typename IntervalSequenceTree< Key, Allocator >::iterator 00548 IntervalSequenceTree< Key, Allocator >::find( 00549 IntervalSequenceTree< Key, Allocator >::size_type point ) 00550 { 00551 return iterator( IntervalSequenceTree< Key, Allocator >::recursiveFind( point, root ) ); 00552 } 00553 00554 template< class Key, class Allocator > 00555 typename IntervalSequenceTree< Key, Allocator >::const_iterator 00556 IntervalSequenceTree< Key, Allocator >::find( 00557 IntervalSequenceTree< Key, Allocator >::size_type point ) const 00558 { 00559 return const_iterator( IntervalSequenceTree< Key, Allocator >::recursiveFind( point, root ) ); 00560 } 00561 00562 template< class Key, class Allocator > 00563 typename IntervalSequenceTree< Key, Allocator >::IstNode* 00564 IntervalSequenceTree< Key, Allocator >::recursiveFind( 00565 IntervalSequenceTree< Key, Allocator >::size_type& point, 00566 IstNode* node ) { 00567 00568 if( node == NULL ) 00569 return NULL; 00570 00571 // return this node if it's a leaf 00572 if( node->key != NULL ) 00573 return node; 00574 // look for the next node to recurse to 00575 if( point < node->length ){ 00576 if( node->left ){ 00577 if( point < node->left->length ) 00578 return recursiveFind( point, node->left ); 00579 point -= node->left->length; 00580 } 00581 return recursiveFind( point, node->right ); 00582 } 00583 point -= node->length; 00584 // out of range 00585 return NULL; 00586 } 00587 00588 template< class Key, class Allocator > 00589 typename IntervalSequenceTree< Key, Allocator >::size_type 00590 IntervalSequenceTree< Key, Allocator >::length() const{ 00591 return root == NULL ? 0 : root->length; 00592 } 00593 00594 template< class Key, class Allocator > 00595 typename IntervalSequenceTree< Key, Allocator >::size_type 00596 IntervalSequenceTree< Key, Allocator >::nodeCount() const{ 00597 return root == NULL ? 0 : root->subtree_size + 1; 00598 } 00599 00600 template< class Key, class Allocator > 00601 typename IntervalSequenceTree< Key, Allocator >::size_type 00602 IntervalSequenceTree< Key, Allocator >::countNodes( IstNode* x ) const{ 00603 if( x == NULL ) 00604 x = root; 00605 if( x->key == NULL ) 00606 return countNodes( x->left ) + countNodes( x->right ) + 1; 00607 return 1; 00608 } 00609 00610 00611 template< class Key, class Allocator > 00612 void IntervalSequenceTree< Key, Allocator >::increment( IstNode*& x) { 00613 // find the least-ancestor with another child 00614 // and set x to that child 00615 while( x->parent != NULL ){ 00616 if( x == x->parent->left && 00617 x->parent->right != NULL ){ 00618 x = x->parent->right; 00619 break; 00620 }else 00621 x = x->parent; 00622 } 00623 // if there were no other children to the right then we're at the end 00624 if( x->parent == NULL ){ 00625 x = NULL; 00626 return; 00627 } 00628 00629 // find the left-most leaf node below x 00630 while( x->key == NULL ){ 00631 if( x->left != NULL ) 00632 x = x->left; 00633 else if( x->right != NULL ) 00634 x = x->right; 00635 } 00636 } 00637 00638 template< class Key, class Allocator > 00639 void IntervalSequenceTree< Key, Allocator >::decrement( IstNode*& x) const{ 00640 if( x != NULL ){ 00641 // find the least-ancestor with another child to the left 00642 // and set x to that child 00643 while( x->parent != NULL ){ 00644 if( x == x->parent->right && 00645 x->parent->left != NULL){ 00646 x = x->parent->left; 00647 break; 00648 }else 00649 x = x->parent; 00650 } 00651 // if there was no other children to the left then we're at the end 00652 // raise hell! (cause an access violation) 00653 if( x->parent == NULL ) 00654 x = NULL; 00655 }else{ 00656 x = root; 00657 } 00658 00659 // find the right-most leaf node below x 00660 while( x->key == NULL ){ 00661 if( x->right != NULL ) 00662 x = x->right; 00663 else if( x->left != NULL ) 00664 x = x->left; 00665 } 00666 } 00667 00668 template< class Key, class Allocator > 00669 void IntervalSequenceTree< Key, Allocator >::deleteSubtree( IstNode*& istn ) { 00670 if( istn->left != NULL ) 00671 deleteSubtree( istn->left ); 00672 if( istn->right != NULL ) 00673 deleteSubtree( istn->right ); 00674 if( istn->key != NULL ) 00675 delete istn->key; 00676 delete istn; 00677 } 00678 00679 00680 #endif // __IntervalSequenceTree_h__

Generated on Mon Feb 14 19:28:19 2005 for libGenome by doxygen 1.3.8