• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

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__, __LINE__ );
00270                                         // root->item = RakNet::OP_NEW<LinkedListType>( __FILE__, __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__, __LINE__ );
00284                                         // root->item = RakNet::OP_NEW<LinkedListType>( __FILE__, __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__, __LINE__ );
00304                                                 // position->item = RakNet::OP_NEW<LinkedListType>( __FILE__, __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__, __LINE__ );
00376                                 // root->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00390                                 // root->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00408                                         // position->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00460                                 // root->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00474                                 // root->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00494                                         // position->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00551                                         // root->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00565                                         // root->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00583                                                 // position->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00624                         // root->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00637                                 // position->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00663                                 // new_node->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00701                         // root->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00716                                 // position->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__ );
00744                                 // new_node->item = RakNet::OP_NEW<CircularLinkedListType>( __FILE__, __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__, __LINE__);
00789                                 RakNet::OP_DELETE(this->root, __FILE__, __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__, __LINE__);
00804                                 RakNet::OP_DELETE(this->position, __FILE__, __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__, __LINE__);}
00958                         {
00959                                 RakNet::OP_DELETE(this->root, __FILE__, __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__, __LINE__);
00974                                         RakNet::OP_DELETE(temp, __FILE__, __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

Generated on Thu Sep 30 2010 01:27:22 for RakNet by  doxygen 1.7.1