Shadowrun: Awakened 29 September 2011 - Build 871
DS_LinkedList.h
Go to the documentation of this file.
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.

GNU Lesser General Public License 3 Sourceforge.net