![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 #ifndef __LINKED_LIST_H 00011 #define __LINKED_LIST_H 00012 00013 #include "Export.h" 00014 #include "RakMemoryOverride.h" 00015 00016 #ifdef _MSC_VER 00017 #pragma warning( push ) 00018 #endif 00019 00022 namespace DataStructures 00023 { 00024 // Prototype to prevent error in CircularLinkedList class when a reference is made to a LinkedList class 00025 template <class LinkedListType> 00026 class RAK_DLL_EXPORT LinkedList; 00027 00144 template <class CircularLinkedListType> 00145 00146 class CircularLinkedList 00147 { 00148 00149 public: 00150 00151 struct node 00152 { 00153 CircularLinkedListType item; 00154 00155 node* previous; 00156 node* next; 00157 }; 00158 00159 CircularLinkedList(); 00160 ~CircularLinkedList(); 00161 CircularLinkedList( const CircularLinkedList& original_copy ); 00162 // CircularLinkedList(LinkedList<CircularLinkedListType> original_copy) {CircularLinkedList(original_copy);} // Converts linked list to circular type 00163 bool operator= ( const CircularLinkedList& original_copy ); 00164 CircularLinkedList& operator++(); // CircularLinkedList A; ++A; 00165 CircularLinkedList& operator++( int ); // Circular_Linked List A; A++; 00166 CircularLinkedList& operator--(); // CircularLinkedList A; --A; 00167 CircularLinkedList& operator--( int ); // Circular_Linked List A; A--; 00168 bool IsIn( const CircularLinkedListType& input ); 00169 bool Find( const CircularLinkedListType& input ); 00170 void Insert( const CircularLinkedListType& input ); 00171 00172 CircularLinkedListType& Add ( const CircularLinkedListType& input ) 00173 00174 ; // Adds after the current position 00175 void Replace( const CircularLinkedListType& input ); 00176 00177 void Del( void ); 00178 00179 unsigned int Size( void ); 00180 00181 CircularLinkedListType& Peek( void ); 00182 00183 CircularLinkedListType Pop( void ); 00184 00185 void Clear( void ); 00186 00187 void Sort( void ); 00188 00189 void Beginning( void ); 00190 00191 void End( void ); 00192 00193 void Concatenate( const CircularLinkedList& L ); 00194 00195 protected: 00196 unsigned int list_size; 00197 00198 node *root; 00199 00200 node *position; 00201 00202 node* FindPointer( const CircularLinkedListType& input ); 00203 00204 private: 00205 CircularLinkedList Merge( CircularLinkedList L1, CircularLinkedList L2 ); 00206 00207 CircularLinkedList Mergesort( const CircularLinkedList& L ); 00208 }; 00209 00210 template <class LinkedListType> 00211 00212 class LinkedList : public CircularLinkedList<LinkedListType> 00213 { 00214 00215 public: 00216 LinkedList() 00217 {} 00218 00219 LinkedList( const LinkedList& original_copy ); 00220 ~LinkedList(); 00221 bool operator= ( const LinkedList<LinkedListType>& original_copy ); 00222 LinkedList& operator++(); // LinkedList A; ++A; 00223 LinkedList& operator++( int ); // Linked List A; A++; 00224 LinkedList& operator--(); // LinkedList A; --A; 00225 LinkedList& operator--( int ); // Linked List A; A--; 00226 00227 private: 00228 LinkedList Merge( LinkedList L1, LinkedList L2 ); 00229 LinkedList Mergesort( const LinkedList& L ); 00230 00231 }; 00232 00233 00234 template <class CircularLinkedListType> 00235 inline void CircularLinkedList<CircularLinkedListType>::Beginning( void ) 00236 { 00237 if ( this->root ) 00238 this->position = this->root; 00239 } 00240 00241 template <class CircularLinkedListType> 00242 inline void CircularLinkedList<CircularLinkedListType>::End( void ) 00243 { 00244 if ( this->root ) 00245 this->position = this->root->previous; 00246 } 00247 00248 template <class LinkedListType> 00249 bool LinkedList<LinkedListType>::operator= ( const LinkedList<LinkedListType>& original_copy ) 00250 { 00251 typename LinkedList::node * original_copy_pointer, *last, *save_position; 00252 00253 if ( ( &original_copy ) != this ) 00254 { 00255 00256 this->Clear(); 00257 00258 00259 if ( original_copy.list_size == 0 ) 00260 { 00261 this->root = 0; 00262 this->position = 0; 00263 this->list_size = 0; 00264 } 00265 00266 else 00267 if ( original_copy.list_size == 1 ) 00268 { 00269 this->root = RakNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ ); 00270 // root->item = RakNet::OP_NEW<LinkedListType>( _FILE_AND_LINE_ ); 00271 this->root->next = this->root; 00272 this->root->previous = this->root; 00273 this->list_size = 1; 00274 this->position = this->root; 00275 // *(root->item)=*((original_copy.root)->item); 00276 this->root->item = original_copy.root->item; 00277 } 00278 00279 else 00280 { 00281 // Setup the first part of the root node 00282 original_copy_pointer = original_copy.root; 00283 this->root = RakNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ ); 00284 // root->item = RakNet::OP_NEW<LinkedListType>( _FILE_AND_LINE_ ); 00285 this->position = this->root; 00286 // *(root->item)=*((original_copy.root)->item); 00287 this->root->item = original_copy.root->item; 00288 00289 if ( original_copy_pointer == original_copy.position ) 00290 save_position = this->position; 00291 00292 do 00293 { 00294 00295 00296 // Save the current element 00297 last = this->position; 00298 00299 // Point to the next node in the source list 00300 original_copy_pointer = original_copy_pointer->next; 00301 00302 // Create a new node and point position to it 00303 this->position = RakNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ ); 00304 // position->item = RakNet::OP_NEW<LinkedListType>( _FILE_AND_LINE_ ); 00305 00306 // Copy the item to the new node 00307 // *(position->item)=*(original_copy_pointer->item); 00308 this->position->item = original_copy_pointer->item; 00309 00310 if ( original_copy_pointer == original_copy.position ) 00311 save_position = this->position; 00312 00313 00314 // Set the previous pointer for the new node 00315 ( this->position->previous ) = last; 00316 00317 // Set the next pointer for the old node to the new node 00318 ( last->next ) = this->position; 00319 00320 } 00321 00322 while ( ( original_copy_pointer->next ) != ( original_copy.root ) ); 00323 00324 // Complete the circle. Set the next pointer of the newest node to the root and the previous pointer of the root to the newest node 00325 this->position->next = this->root; 00326 00327 this->root->previous = this->position; 00328 00329 this->list_size = original_copy.list_size; 00330 00331 this->position = save_position; 00332 } 00333 } 00334 00335 return true; 00336 } 00337 00338 00339 template <class CircularLinkedListType> 00340 CircularLinkedList<CircularLinkedListType>::CircularLinkedList() 00341 { 00342 this->root = 0; 00343 this->position = 0; 00344 this->list_size = 0; 00345 } 00346 00347 template <class CircularLinkedListType> 00348 CircularLinkedList<CircularLinkedListType>::~CircularLinkedList() 00349 { 00350 this->Clear(); 00351 } 00352 00353 template <class LinkedListType> 00354 LinkedList<LinkedListType>::~LinkedList() 00355 { 00356 this->Clear(); 00357 } 00358 00359 template <class LinkedListType> 00360 LinkedList<LinkedListType>::LinkedList( const LinkedList& original_copy ) 00361 { 00362 typename LinkedList::node * original_copy_pointer, *last, *save_position; 00363 00364 if ( original_copy.list_size == 0 ) 00365 { 00366 this->root = 0; 00367 this->position = 0; 00368 this->list_size = 0; 00369 return ; 00370 } 00371 00372 else 00373 if ( original_copy.list_size == 1 ) 00374 { 00375 this->root = RakNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ ); 00376 // root->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00377 this->root->next = this->root; 00378 this->root->previous = this->root; 00379 this->list_size = 1; 00380 this->position = this->root; 00381 // *(root->item) = *((original_copy.root)->item); 00382 this->root->item = original_copy.root->item; 00383 } 00384 00385 else 00386 { 00387 // Setup the first part of the root node 00388 original_copy_pointer = original_copy.root; 00389 this->root = RakNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ ); 00390 // root->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00391 this->position = this->root; 00392 // *(root->item)=*((original_copy.root)->item); 00393 this->root->item = original_copy.root->item; 00394 00395 if ( original_copy_pointer == original_copy.position ) 00396 save_position = this->position; 00397 00398 do 00399 { 00400 // Save the current element 00401 last = this->position; 00402 00403 // Point to the next node in the source list 00404 original_copy_pointer = original_copy_pointer->next; 00405 00406 // Create a new node and point position to it 00407 this->position = RakNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ ); 00408 // position->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00409 00410 // Copy the item to the new node 00411 // *(position->item)=*(original_copy_pointer->item); 00412 this->position->item = original_copy_pointer->item; 00413 00414 if ( original_copy_pointer == original_copy.position ) 00415 save_position = this->position; 00416 00417 // Set the previous pointer for the new node 00418 ( this->position->previous ) = last; 00419 00420 // Set the next pointer for the old node to the new node 00421 ( last->next ) = this->position; 00422 00423 } 00424 00425 while ( ( original_copy_pointer->next ) != ( original_copy.root ) ); 00426 00427 // Complete the circle. Set the next pointer of the newest node to the root and the previous pointer of the root to the newest node 00428 this->position->next = this->root; 00429 00430 this->root->previous = this->position; 00431 00432 this->list_size = original_copy.list_size; 00433 00434 this->position = save_position; 00435 } 00436 } 00437 00438 #ifdef _MSC_VER 00439 #pragma warning( disable : 4701 ) // warning C4701: local variable <variable name> may be used without having been initialized 00440 #endif 00441 template <class CircularLinkedListType> 00442 CircularLinkedList<CircularLinkedListType>::CircularLinkedList( const CircularLinkedList& original_copy ) 00443 { 00444 node * original_copy_pointer; 00445 node *last; 00446 node *save_position; 00447 00448 if ( original_copy.list_size == 0 ) 00449 { 00450 this->root = 0; 00451 this->position = 0; 00452 this->list_size = 0; 00453 return ; 00454 } 00455 00456 else 00457 if ( original_copy.list_size == 1 ) 00458 { 00459 this->root = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00460 // root->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00461 this->root->next = this->root; 00462 this->root->previous = this->root; 00463 this->list_size = 1; 00464 this->position = this->root; 00465 // *(root->item) = *((original_copy.root)->item); 00466 this->root->item = original_copy.root->item; 00467 } 00468 00469 else 00470 { 00471 // Setup the first part of the root node 00472 original_copy_pointer = original_copy.root; 00473 this->root = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00474 // root->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00475 this->position = this->root; 00476 // *(root->item)=*((original_copy.root)->item); 00477 this->root->item = original_copy.root->item; 00478 00479 if ( original_copy_pointer == original_copy.position ) 00480 save_position = this->position; 00481 00482 do 00483 { 00484 00485 00486 // Save the current element 00487 last = this->position; 00488 00489 // Point to the next node in the source list 00490 original_copy_pointer = original_copy_pointer->next; 00491 00492 // Create a new node and point position to it 00493 this->position = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00494 // position->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00495 00496 // Copy the item to the new node 00497 // *(position->item)=*(original_copy_pointer->item); 00498 this->position->item = original_copy_pointer->item; 00499 00500 if ( original_copy_pointer == original_copy.position ) 00501 save_position = position; 00502 00503 // Set the previous pointer for the new node 00504 ( this->position->previous ) = last; 00505 00506 // Set the next pointer for the old node to the new node 00507 ( last->next ) = this->position; 00508 00509 } 00510 00511 while ( ( original_copy_pointer->next ) != ( original_copy.root ) ); 00512 00513 // Complete the circle. Set the next pointer of the newest node to the root and the previous pointer of the root to the newest node 00514 this->position->next = this->root; 00515 00516 this->root->previous = position; 00517 00518 this->list_size = original_copy.list_size; 00519 00520 this->position = save_position; 00521 } 00522 } 00523 00524 #ifdef _MSC_VER 00525 #pragma warning( disable : 4701 ) // warning C4701: local variable <variable name> may be used without having been initialized 00526 #endif 00527 template <class CircularLinkedListType> 00528 bool CircularLinkedList<CircularLinkedListType>::operator= ( const CircularLinkedList& original_copy ) 00529 { 00530 node * original_copy_pointer; 00531 node *last; 00532 node *save_position; 00533 00534 if ( ( &original_copy ) != this ) 00535 { 00536 00537 this->Clear(); 00538 00539 00540 if ( original_copy.list_size == 0 ) 00541 { 00542 this->root = 0; 00543 this->position = 0; 00544 this->list_size = 0; 00545 } 00546 00547 else 00548 if ( original_copy.list_size == 1 ) 00549 { 00550 this->root = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00551 // root->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00552 this->root->next = this->root; 00553 this->root->previous = this->root; 00554 this->list_size = 1; 00555 this->position = this->root; 00556 // *(root->item)=*((original_copy.root)->item); 00557 this->root->item = original_copy.root->item; 00558 } 00559 00560 else 00561 { 00562 // Setup the first part of the root node 00563 original_copy_pointer = original_copy.root; 00564 this->root = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00565 // root->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00566 this->position = this->root; 00567 // *(root->item)=*((original_copy.root)->item); 00568 this->root->item = original_copy.root->item; 00569 00570 if ( original_copy_pointer == original_copy.position ) 00571 save_position = this->position; 00572 00573 do 00574 { 00575 // Save the current element 00576 last = this->position; 00577 00578 // Point to the next node in the source list 00579 original_copy_pointer = original_copy_pointer->next; 00580 00581 // Create a new node and point position to it 00582 this->position = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00583 // position->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00584 00585 // Copy the item to the new node 00586 // *(position->item)=*(original_copy_pointer->item); 00587 this->position->item = original_copy_pointer->item; 00588 00589 if ( original_copy_pointer == original_copy.position ) 00590 save_position = this->position; 00591 00592 // Set the previous pointer for the new node 00593 ( this->position->previous ) = last; 00594 00595 // Set the next pointer for the old node to the new node 00596 ( last->next ) = this->position; 00597 00598 } 00599 00600 while ( ( original_copy_pointer->next ) != ( original_copy.root ) ); 00601 00602 // Complete the circle. Set the next pointer of the newest node to the root and the previous pointer of the root to the newest node 00603 this->position->next = this->root; 00604 00605 this->root->previous = this->position; 00606 00607 this->list_size = original_copy.list_size; 00608 00609 this->position = save_position; 00610 } 00611 } 00612 00613 return true; 00614 } 00615 00616 template <class CircularLinkedListType> 00617 void CircularLinkedList<CircularLinkedListType>::Insert( const CircularLinkedListType& input ) 00618 { 00619 node * new_node; 00620 00621 if ( list_size == 0 ) 00622 { 00623 this->root = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00624 // root->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00625 //*(root->item)=input; 00626 this->root->item = input; 00627 this->root->next = this->root; 00628 this->root->previous = this->root; 00629 this->list_size = 1; 00630 this->position = this->root; 00631 } 00632 00633 else 00634 if ( list_size == 1 ) 00635 { 00636 this->position = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00637 // position->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00638 this->root->next = this->position; 00639 this->root->previous = this->position; 00640 this->position->previous = this->root; 00641 this->position->next = this->root; 00642 // *(position->item)=input; 00643 this->position->item = input; 00644 this->root = this->position; // Since we're inserting into a 1 element list the old root is now the second item 00645 this->list_size = 2; 00646 } 00647 00648 else 00649 { 00650 /* 00651 00652 B 00653 | 00654 A --- C 00655 00656 position->previous=A 00657 new_node=B 00658 position=C 00659 00660 Note that the order of the following statements is important */ 00661 00662 new_node = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00663 // new_node->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00664 00665 // *(new_node->item)=input; 00666 new_node->item = input; 00667 00668 // Point next of A to B 00669 ( this->position->previous ) ->next = new_node; 00670 00671 // Point last of B to A 00672 new_node->previous = this->position->previous; 00673 00674 // Point last of C to B 00675 this->position->previous = new_node; 00676 00677 // Point next of B to C 00678 new_node->next = this->position; 00679 00680 // Since the root pointer is bound to a node rather than an index this moves it back if you insert an element at the root 00681 00682 if ( this->position == this->root ) 00683 { 00684 this->root = new_node; 00685 this->position = this->root; 00686 } 00687 00688 // Increase the recorded size of the list by one 00689 this->list_size++; 00690 } 00691 } 00692 00693 template <class CircularLinkedListType> 00694 CircularLinkedListType& CircularLinkedList<CircularLinkedListType>::Add ( const CircularLinkedListType& input ) 00695 { 00696 node * new_node; 00697 00698 if ( this->list_size == 0 ) 00699 { 00700 this->root = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00701 // root->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00702 // *(root->item)=input; 00703 this->root->item = input; 00704 this->root->next = this->root; 00705 this->root->previous = this->root; 00706 this->list_size = 1; 00707 this->position = this->root; 00708 // return *(position->item); 00709 return this->position->item; 00710 } 00711 00712 else 00713 if ( list_size == 1 ) 00714 { 00715 this->position = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00716 // position->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00717 this->root->next = this->position; 00718 this->root->previous = this->position; 00719 this->position->previous = this->root; 00720 this->position->next = this->root; 00721 // *(position->item)=input; 00722 this->position->item = input; 00723 this->list_size = 2; 00724 this->position = this->root; // Don't move the position from the root 00725 // return *(position->item); 00726 return this->position->item; 00727 } 00728 00729 else 00730 { 00731 /* 00732 00733 B 00734 | 00735 A --- C 00736 00737 new_node=B 00738 position=A 00739 position->next=C 00740 00741 Note that the order of the following statements is important */ 00742 00743 new_node = RakNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ ); 00744 // new_node->item = RakNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ ); 00745 00746 // *(new_node->item)=input; 00747 new_node->item = input; 00748 00749 // Point last of B to A 00750 new_node->previous = this->position; 00751 00752 // Point next of B to C 00753 new_node->next = ( this->position->next ); 00754 00755 // Point last of C to B 00756 ( this->position->next ) ->previous = new_node; 00757 00758 // Point next of A to B 00759 ( this->position->next ) = new_node; 00760 00761 // Increase the recorded size of the list by one 00762 this->list_size++; 00763 00764 // return *(new_node->item); 00765 return new_node->item; 00766 } 00767 } 00768 00769 template <class CircularLinkedListType> 00770 inline void CircularLinkedList<CircularLinkedListType>::Replace( const CircularLinkedListType& input ) 00771 { 00772 if ( this->list_size > 0 ) 00773 // *(position->item)=input; 00774 this->position->item = input; 00775 } 00776 00777 template <class CircularLinkedListType> 00778 void CircularLinkedList<CircularLinkedListType>::Del() 00779 { 00780 node * new_position; 00781 00782 if ( this->list_size == 0 ) 00783 return ; 00784 00785 else 00786 if ( this->list_size == 1 ) 00787 { 00788 // RakNet::OP_DELETE(root->item, _FILE_AND_LINE_); 00789 RakNet::OP_DELETE(this->root, _FILE_AND_LINE_); 00790 this->root = this->position = 0; 00791 this->list_size = 0; 00792 } 00793 00794 else 00795 { 00796 ( this->position->previous ) ->next = this->position->next; 00797 ( this->position->next ) ->previous = this->position->previous; 00798 new_position = this->position->next; 00799 00800 if ( this->position == this->root ) 00801 this->root = new_position; 00802 00803 // RakNet::OP_DELETE(position->item, _FILE_AND_LINE_); 00804 RakNet::OP_DELETE(this->position, _FILE_AND_LINE_); 00805 00806 this->position = new_position; 00807 00808 this->list_size--; 00809 } 00810 } 00811 00812 template <class CircularLinkedListType> 00813 bool CircularLinkedList<CircularLinkedListType>::IsIn(const CircularLinkedListType& input ) 00814 { 00815 node * return_value, *old_position; 00816 00817 old_position = this->position; 00818 00819 return_value = FindPointer( input ); 00820 this->position = old_position; 00821 00822 if ( return_value != 0 ) 00823 return true; 00824 else 00825 return false; // Can't find the item don't do anything 00826 } 00827 00828 template <class CircularLinkedListType> 00829 bool CircularLinkedList<CircularLinkedListType>::Find( const CircularLinkedListType& input ) 00830 { 00831 node * return_value; 00832 00833 return_value = FindPointer( input ); 00834 00835 if ( return_value != 0 ) 00836 { 00837 this->position = return_value; 00838 return true; 00839 } 00840 00841 else 00842 return false; // Can't find the item don't do anything 00843 } 00844 00845 template <class CircularLinkedListType> 00846 typename CircularLinkedList<CircularLinkedListType>::node* CircularLinkedList<CircularLinkedListType>::FindPointer( const CircularLinkedListType& input ) 00847 { 00848 node * current; 00849 00850 if ( this->list_size == 0 ) 00851 return 0; 00852 00853 current = this->root; 00854 00855 // Search for the item starting from the root node and incrementing the pointer after every check 00856 // If you wind up pointing at the root again you looped around the list so didn't find the item, in which case return 0 00857 do 00858 { 00859 // if (*(current->item) == input) return current; 00860 00861 if ( current->item == input ) 00862 return current; 00863 00864 current = current->next; 00865 } 00866 00867 while ( current != this->root ); 00868 00869 return 0; 00870 00871 } 00872 00873 template <class CircularLinkedListType> 00874 inline unsigned int CircularLinkedList<CircularLinkedListType>::Size( void ) 00875 { 00876 return this->list_size; 00877 } 00878 00879 template <class CircularLinkedListType> 00880 inline CircularLinkedListType& CircularLinkedList<CircularLinkedListType>::Peek( void ) 00881 { 00882 // return *(position->item); 00883 return this->position->item; 00884 } 00885 00886 template <class CircularLinkedListType> 00887 CircularLinkedListType CircularLinkedList<CircularLinkedListType>::Pop( void ) 00888 { 00889 CircularLinkedListType element; 00890 element = Peek(); 00891 Del(); 00892 return CircularLinkedListType( element ); // return temporary 00893 } 00894 00895 // Prefix 00896 template <class CircularLinkedListType> 00897 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator++() 00898 { 00899 if ( this->list_size != 0 ) 00900 position = position->next; 00901 00902 return *this; 00903 } 00904 00905 /* 00906 // Postfix 00907 template <class CircularLinkedListType> 00908 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator++(int) 00909 { 00910 CircularLinkedList<CircularLinkedListType> before; 00911 before=*this; 00912 operator++(); 00913 return before; 00914 } 00915 */ 00916 00917 template <class CircularLinkedListType> 00918 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator++( int ) 00919 { 00920 return this->operator++(); 00921 } 00922 00923 // Prefix 00924 template <class CircularLinkedListType> 00925 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator--() 00926 { 00927 if ( this->list_size != 0 ) 00928 this->position = this->position->previous; 00929 00930 return *this; 00931 } 00932 00933 /* 00934 // Postfix 00935 template <class CircularLinkedListType> 00936 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator--(int) 00937 { 00938 CircularLinkedList<CircularLinkedListType> before; 00939 before=*this; 00940 operator--(); 00941 return before; 00942 } 00943 */ 00944 00945 template <class CircularLinkedListType> 00946 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator--( int ) 00947 { 00948 return this->operator--(); 00949 } 00950 00951 template <class CircularLinkedListType> 00952 void CircularLinkedList<CircularLinkedListType>::Clear( void ) 00953 { 00954 if ( this->list_size == 0 ) 00955 return ; 00956 else 00957 if ( this->list_size == 1 ) // {RakNet::OP_DELETE(root->item); RakNet::OP_DELETE(root, _FILE_AND_LINE_);} 00958 { 00959 RakNet::OP_DELETE(this->root, _FILE_AND_LINE_); 00960 } 00961 00962 else 00963 { 00964 node* current; 00965 node* temp; 00966 00967 current = this->root; 00968 00969 do 00970 { 00971 temp = current; 00972 current = current->next; 00973 // RakNet::OP_DELETE(temp->item, _FILE_AND_LINE_); 00974 RakNet::OP_DELETE(temp, _FILE_AND_LINE_); 00975 } 00976 00977 while ( current != this->root ); 00978 } 00979 00980 this->list_size = 0; 00981 this->root = 0; 00982 this->position = 0; 00983 } 00984 00985 template <class CircularLinkedListType> 00986 inline void CircularLinkedList<CircularLinkedListType>::Concatenate( const CircularLinkedList<CircularLinkedListType>& L ) 00987 { 00988 unsigned int counter; 00989 node* ptr; 00990 00991 if ( L.list_size == 0 ) 00992 return ; 00993 00994 if ( this->list_size == 0 ) 00995 * this = L; 00996 00997 ptr = L.root; 00998 00999 this->position = this->root->previous; 01000 01001 // Cycle through each element in L and add it to the current list 01002 for ( counter = 0; counter < L.list_size; counter++ ) 01003 { 01004 // Add item after the current item pointed to 01005 // add(*(ptr->item)); 01006 01007 Add ( ptr->item ); 01008 01009 // Update pointers. Moving ptr keeps the current pointer at the end of the list since the add function does not move the pointer 01010 ptr = ptr->next; 01011 01012 this->position = this->position->next; 01013 } 01014 } 01015 01016 template <class CircularLinkedListType> 01017 inline void CircularLinkedList<CircularLinkedListType>::Sort( void ) 01018 { 01019 if ( this->list_size <= 1 ) 01020 return ; 01021 01022 // Call equal operator to assign result of mergesort to current object 01023 *this = Mergesort( *this ); 01024 01025 this->position = this->root; 01026 } 01027 01028 template <class CircularLinkedListType> 01029 CircularLinkedList<CircularLinkedListType> CircularLinkedList<CircularLinkedListType>::Mergesort( const CircularLinkedList& L ) 01030 { 01031 unsigned int counter; 01032 node* location; 01033 CircularLinkedList<CircularLinkedListType> L1; 01034 CircularLinkedList<CircularLinkedListType> L2; 01035 01036 location = L.root; 01037 01038 // Split the list into two equal size sublists, L1 and L2 01039 01040 for ( counter = 0; counter < L.list_size / 2; counter++ ) 01041 { 01042 // L1.add (*(location->item)); 01043 L1.Add ( location->item ); 01044 location = location->next; 01045 } 01046 01047 for ( ;counter < L.list_size; counter++ ) 01048 { 01049 // L2.Add(*(location->item)); 01050 L2.Add ( location->item ); 01051 location = location->next; 01052 } 01053 01054 // Recursively sort the sublists 01055 if ( L1.list_size > 1 ) 01056 L1 = Mergesort( L1 ); 01057 01058 if ( L2.list_size > 1 ) 01059 L2 = Mergesort( L2 ); 01060 01061 // Merge the two sublists 01062 return Merge( L1, L2 ); 01063 } 01064 01065 template <class CircularLinkedListType> 01066 CircularLinkedList<CircularLinkedListType> CircularLinkedList<CircularLinkedListType>::Merge( CircularLinkedList L1, CircularLinkedList L2 ) 01067 { 01068 CircularLinkedList<CircularLinkedListType> X; 01069 CircularLinkedListType element; 01070 L1.position = L1.root; 01071 L2.position = L2.root; 01072 01073 // While neither list is empty 01074 01075 while ( ( L1.list_size != 0 ) && ( L2.list_size != 0 ) ) 01076 { 01077 // Compare the first items of L1 and L2 01078 // Remove the smaller of the two items from the list 01079 01080 if ( ( ( L1.root ) ->item ) < ( ( L2.root ) ->item ) ) 01081 // if ((*((L1.root)->item)) < (*((L2.root)->item))) 01082 { 01083 // element = *((L1.root)->item); 01084 element = ( L1.root ) ->item; 01085 L1.Del(); 01086 } 01087 else 01088 { 01089 // element = *((L2.root)->item); 01090 element = ( L2.root ) ->item; 01091 L2.Del(); 01092 } 01093 01094 // Add this item to the end of X 01095 X.Add( element ); 01096 01097 X++; 01098 } 01099 01100 // Add the remaining list to X 01101 if ( L1.list_size != 0 ) 01102 X.Concatenate( L1 ); 01103 else 01104 X.Concatenate( L2 ); 01105 01106 return X; 01107 } 01108 01109 template <class LinkedListType> 01110 LinkedList<LinkedListType> LinkedList<LinkedListType>::Mergesort( const LinkedList& L ) 01111 { 01112 unsigned int counter; 01113 typename LinkedList::node* location; 01114 LinkedList<LinkedListType> L1; 01115 LinkedList<LinkedListType> L2; 01116 01117 location = L.root; 01118 01119 // Split the list into two equal size sublists, L1 and L2 01120 01121 for ( counter = 0; counter < L.LinkedList_size / 2; counter++ ) 01122 { 01123 // L1.add (*(location->item)); 01124 L1.Add ( location->item ); 01125 location = location->next; 01126 } 01127 01128 for ( ;counter < L.LinkedList_size; counter++ ) 01129 { 01130 // L2.Add(*(location->item)); 01131 L2.Add ( location->item ); 01132 location = location->next; 01133 } 01134 01135 // Recursively sort the sublists 01136 if ( L1.list_size > 1 ) 01137 L1 = Mergesort( L1 ); 01138 01139 if ( L2.list_size > 1 ) 01140 L2 = Mergesort( L2 ); 01141 01142 // Merge the two sublists 01143 return Merge( L1, L2 ); 01144 } 01145 01146 template <class LinkedListType> 01147 LinkedList<LinkedListType> LinkedList<LinkedListType>::Merge( LinkedList L1, LinkedList L2 ) 01148 { 01149 LinkedList<LinkedListType> X; 01150 LinkedListType element; 01151 L1.position = L1.root; 01152 L2.position = L2.root; 01153 01154 // While neither list is empty 01155 01156 while ( ( L1.LinkedList_size != 0 ) && ( L2.LinkedList_size != 0 ) ) 01157 { 01158 // Compare the first items of L1 and L2 01159 // Remove the smaller of the two items from the list 01160 01161 if ( ( ( L1.root ) ->item ) < ( ( L2.root ) ->item ) ) 01162 // if ((*((L1.root)->item)) < (*((L2.root)->item))) 01163 { 01164 element = ( L1.root ) ->item; 01165 // element = *((L1.root)->item); 01166 L1.Del(); 01167 } 01168 else 01169 { 01170 element = ( L2.root ) ->item; 01171 // element = *((L2.root)->item); 01172 L2.Del(); 01173 } 01174 01175 // Add this item to the end of X 01176 X.Add( element ); 01177 } 01178 01179 // Add the remaining list to X 01180 if ( L1.LinkedList_size != 0 ) 01181 X.concatenate( L1 ); 01182 else 01183 X.concatenate( L2 ); 01184 01185 return X; 01186 } 01187 01188 01189 // Prefix 01190 template <class LinkedListType> 01191 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator++() 01192 { 01193 if ( ( this->list_size != 0 ) && ( this->position->next != this->root ) ) 01194 this->position = this->position->next; 01195 01196 return *this; 01197 } 01198 01199 /* 01200 // Postfix 01201 template <class LinkedListType> 01202 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator++(int) 01203 { 01204 LinkedList<LinkedListType> before; 01205 before=*this; 01206 operator++(); 01207 return before; 01208 } 01209 */ 01210 // Postfix 01211 template <class LinkedListType> 01212 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator++( int ) 01213 { 01214 return this->operator++(); 01215 } 01216 01217 // Prefix 01218 template <class LinkedListType> 01219 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator--() 01220 { 01221 if ( ( this->list_size != 0 ) && ( this->position != this->root ) ) 01222 this->position = this->position->previous; 01223 01224 return *this; 01225 } 01226 01227 /* 01228 // Postfix 01229 template <class LinkedListType> 01230 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator--(int) 01231 { 01232 LinkedList<LinkedListType> before; 01233 before=*this; 01234 operator--(); 01235 return before; 01236 } 01237 */ 01238 01239 // Postfix 01240 template <class LinkedListType> 01241 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator--( int ) 01242 { 01243 return this->operator--(); 01244 } 01245 01246 } // End namespace 01247 01248 #ifdef _MSC_VER 01249 #pragma warning( pop ) 01250 #endif 01251 01252 #endif
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.