SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DS_LinkedList.h
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2016-2017, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
20
21
22 #ifndef __LINKED_LIST_H
23 #define __LINKED_LIST_H
24
25 #include "Export.h"
26 #include "memoryoverride.h"
27
30 namespace DataStructures
31 {
32 // Prototype to prevent error in CircularLinkedList class when a reference is made to a LinkedList class
33 template <class LinkedListType>
34 class RAK_DLL_EXPORT LinkedList;
35
151 template <class CircularLinkedListType>
152
153 class CircularLinkedList
154 {
155
156 public:
157
158 struct node
159 {
160 CircularLinkedListType item;
161
162 node* previous;
163 node* next;
164 };
165
166 CircularLinkedList();
167 ~CircularLinkedList();
168 CircularLinkedList( const CircularLinkedList& original_copy );
169 // CircularLinkedList(LinkedList<CircularLinkedListType> original_copy) {CircularLinkedList(original_copy);} // Converts linked list to circular type
170 bool operator= ( const CircularLinkedList& original_copy );
171 CircularLinkedList& operator++(); // CircularLinkedList A; ++A;
172 CircularLinkedList& operator++( int ); // Circular_Linked List A; A++;
173 CircularLinkedList& operator--(); // CircularLinkedList A; --A;
174 CircularLinkedList& operator--( int ); // Circular_Linked List A; A--;
175 bool IsIn( const CircularLinkedListType& input );
176 bool Find( const CircularLinkedListType& input );
177 void Insert( const CircularLinkedListType& input );
178
179 CircularLinkedListType& Add ( const CircularLinkedListType& input )
180
181 ; // Adds after the current position
182 void Replace( const CircularLinkedListType& input );
183
184 void Del( void );
185
186 unsigned int Size( void );
187
188 CircularLinkedListType& Peek( void );
189
190 CircularLinkedListType Pop( void );
191
192 void Clear( void );
193
194 void Sort( void );
195
196 void Beginning( void );
197
198 void End( void );
199
200 void Concatenate( const CircularLinkedList& L );
201
202 protected:
203 unsigned int list_size;
204
205 node *root;
206
207 node *position;
208
209 node* FindPointer( const CircularLinkedListType& input );
210
211 private:
212 CircularLinkedList Merge( CircularLinkedList L1, CircularLinkedList L2 );
213
214 CircularLinkedList Mergesort( const CircularLinkedList& L );
215 };
216
217 template <class LinkedListType>
218
219 class LinkedList : public CircularLinkedList<LinkedListType>
220 {
221
222 public:
223 LinkedList()
224 {}
225
226 LinkedList( const LinkedList& original_copy );
227 ~LinkedList();
228 bool operator= ( const LinkedList<LinkedListType>& original_copy );
229 LinkedList& operator++(); // LinkedList A; ++A;
230 LinkedList& operator++( int ); // Linked List A; A++;
231 LinkedList& operator--(); // LinkedList A; --A;
232 LinkedList& operator--( int ); // Linked List A; A--;
233
234 private:
235 LinkedList Merge( LinkedList L1, LinkedList L2 );
236 LinkedList Mergesort( const LinkedList& L );
237
238 };
239
240
241 template <class CircularLinkedListType>
242 inline void CircularLinkedList<CircularLinkedListType>::Beginning( void )
243 {
244 if ( this->root )
245 this->position = this->root;
246 }
247
248 template <class CircularLinkedListType>
249 inline void CircularLinkedList<CircularLinkedListType>::End( void )
250 {
251 if ( this->root )
252 this->position = this->root->previous;
253 }
254
255 template <class LinkedListType>
256 bool LinkedList<LinkedListType>::operator= ( const LinkedList<LinkedListType>& original_copy )
257 {
258 typename LinkedList::node * original_copy_pointer, *last, *save_position;
259
260 if ( ( &original_copy ) != this )
261 {
262
263 this->Clear();
264
265
266 if ( original_copy.list_size == 0 )
267 {
268 this->root = 0;
269 this->position = 0;
270 this->list_size = 0;
271 }
272
273 else
274 if ( original_copy.list_size == 1 )
275 {
276 this->root = SLNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ );
277 // root->item = SLNet::OP_NEW<LinkedListType>( _FILE_AND_LINE_ );
278 this->root->next = this->root;
279 this->root->previous = this->root;
280 this->list_size = 1;
281 this->position = this->root;
282 // *(root->item)=*((original_copy.root)->item);
283 this->root->item = original_copy.root->item;
284 }
285
286 else
287 {
288 // Setup the first part of the root node
289 original_copy_pointer = original_copy.root;
290 this->root = SLNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ );
291 // root->item = SLNet::OP_NEW<LinkedListType>( _FILE_AND_LINE_ );
292 this->position = this->root;
293 // *(root->item)=*((original_copy.root)->item);
294 this->root->item = original_copy.root->item;
295
296 if ( original_copy_pointer == original_copy.position )
297 save_position = this->position;
298
299 do
300 {
301
302
303 // Save the current element
304 last = this->position;
305
306 // Point to the next node in the source list
307 original_copy_pointer = original_copy_pointer->next;
308
309 // Create a new node and point position to it
310 this->position = SLNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ );
311 // position->item = SLNet::OP_NEW<LinkedListType>( _FILE_AND_LINE_ );
312
313 // Copy the item to the new node
314 // *(position->item)=*(original_copy_pointer->item);
315 this->position->item = original_copy_pointer->item;
316
317 if ( original_copy_pointer == original_copy.position )
318 save_position = this->position;
319
320
321 // Set the previous pointer for the new node
322 ( this->position->previous ) = last;
323
324 // Set the next pointer for the old node to the new node
325 ( last->next ) = this->position;
326
327 }
328
329 while ( ( original_copy_pointer->next ) != ( original_copy.root ) );
330
331 // 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
332 this->position->next = this->root;
333
334 this->root->previous = this->position;
335
336 this->list_size = original_copy.list_size;
337
338 this->position = save_position;
339 }
340 }
341
342 return true;
343 }
344
345
346 template <class CircularLinkedListType>
347 CircularLinkedList<CircularLinkedListType>::CircularLinkedList()
348 {
349 this->root = 0;
350 this->position = 0;
351 this->list_size = 0;
352 }
353
354 template <class CircularLinkedListType>
355 CircularLinkedList<CircularLinkedListType>::~CircularLinkedList()
356 {
357 this->Clear();
358 }
359
360 template <class LinkedListType>
361 LinkedList<LinkedListType>::~LinkedList()
362 {
363 this->Clear();
364 }
365
366 template <class LinkedListType>
367 LinkedList<LinkedListType>::LinkedList( const LinkedList& original_copy )
368 {
369 typename LinkedList::node * original_copy_pointer, *last, *save_position;
370
371 if ( original_copy.list_size == 0 )
372 {
373 this->root = 0;
374 this->position = 0;
375 this->list_size = 0;
376 return ;
377 }
378
379 else
380 if ( original_copy.list_size == 1 )
381 {
382 this->root = SLNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ );
383 // root->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
384 this->root->next = this->root;
385 this->root->previous = this->root;
386 this->list_size = 1;
387 this->position = this->root;
388 // *(root->item) = *((original_copy.root)->item);
389 this->root->item = original_copy.root->item;
390 }
391
392 else
393 {
394 // Setup the first part of the root node
395 original_copy_pointer = original_copy.root;
396 this->root = SLNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ );
397 // root->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
398 this->position = this->root;
399 // *(root->item)=*((original_copy.root)->item);
400 this->root->item = original_copy.root->item;
401
402 if ( original_copy_pointer == original_copy.position )
403 save_position = this->position;
404
405 do
406 {
407 // Save the current element
408 last = this->position;
409
410 // Point to the next node in the source list
411 original_copy_pointer = original_copy_pointer->next;
412
413 // Create a new node and point position to it
414 this->position = SLNet::OP_NEW<typename LinkedList::node>( _FILE_AND_LINE_ );
415 // position->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
416
417 // Copy the item to the new node
418 // *(position->item)=*(original_copy_pointer->item);
419 this->position->item = original_copy_pointer->item;
420
421 if ( original_copy_pointer == original_copy.position )
422 save_position = this->position;
423
424 // Set the previous pointer for the new node
425 ( this->position->previous ) = last;
426
427 // Set the next pointer for the old node to the new node
428 ( last->next ) = this->position;
429
430 }
431
432 while ( ( original_copy_pointer->next ) != ( original_copy.root ) );
433
434 // 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
435 this->position->next = this->root;
436
437 this->root->previous = this->position;
438
439 this->list_size = original_copy.list_size;
440
441 this->position = save_position;
442 }
443 }
444
445 template <class CircularLinkedListType>
446 CircularLinkedList<CircularLinkedListType>::CircularLinkedList( const CircularLinkedList& original_copy )
447 {
448 node * original_copy_pointer;
449 node *last;
450 node *save_position = nullptr;
451
452 if ( original_copy.list_size == 0 )
453 {
454 this->root = 0;
455 this->position = 0;
456 this->list_size = 0;
457 return ;
458 }
459
460 else
461 if ( original_copy.list_size == 1 )
462 {
463 this->root = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
464 // root->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
465 this->root->next = this->root;
466 this->root->previous = this->root;
467 this->list_size = 1;
468 this->position = this->root;
469 // *(root->item) = *((original_copy.root)->item);
470 this->root->item = original_copy.root->item;
471 }
472
473 else
474 {
475 // Setup the first part of the root node
476 original_copy_pointer = original_copy.root;
477 this->root = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
478 // root->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
479 this->position = this->root;
480 // *(root->item)=*((original_copy.root)->item);
481 this->root->item = original_copy.root->item;
482
483 if ( original_copy_pointer == original_copy.position )
484 save_position = this->position;
485
486 do
487 {
488
489
490 // Save the current element
491 last = this->position;
492
493 // Point to the next node in the source list
494 original_copy_pointer = original_copy_pointer->next;
495
496 // Create a new node and point position to it
497 this->position = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
498 // position->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
499
500 // Copy the item to the new node
501 // *(position->item)=*(original_copy_pointer->item);
502 this->position->item = original_copy_pointer->item;
503
504 if ( original_copy_pointer == original_copy.position )
505 save_position = position;
506
507 // Set the previous pointer for the new node
508 ( this->position->previous ) = last;
509
510 // Set the next pointer for the old node to the new node
511 ( last->next ) = this->position;
512
513 }
514
515 while ( ( original_copy_pointer->next ) != ( original_copy.root ) );
516
517 // 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
518 this->position->next = this->root;
519
520 this->root->previous = position;
521
522 this->list_size = original_copy.list_size;
523
524 this->position = save_position;
525 }
526 }
527
528 template <class CircularLinkedListType>
529 bool CircularLinkedList<CircularLinkedListType>::operator= ( const CircularLinkedList& original_copy )
530 {
531 node * original_copy_pointer;
532 node *last;
533 node *save_position = nullptr;
534
535 if ( ( &original_copy ) != this )
536 {
537
538 this->Clear();
539
540
541 if ( original_copy.list_size == 0 )
542 {
543 this->root = 0;
544 this->position = 0;
545 this->list_size = 0;
546 }
547
548 else
549 if ( original_copy.list_size == 1 )
550 {
551 this->root = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
552 // root->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
553 this->root->next = this->root;
554 this->root->previous = this->root;
555 this->list_size = 1;
556 this->position = this->root;
557 // *(root->item)=*((original_copy.root)->item);
558 this->root->item = original_copy.root->item;
559 }
560
561 else
562 {
563 // Setup the first part of the root node
564 original_copy_pointer = original_copy.root;
565 this->root = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
566 // root->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
567 this->position = this->root;
568 // *(root->item)=*((original_copy.root)->item);
569 this->root->item = original_copy.root->item;
570
571 if ( original_copy_pointer == original_copy.position )
572 save_position = this->position;
573
574 do
575 {
576 // Save the current element
577 last = this->position;
578
579 // Point to the next node in the source list
580 original_copy_pointer = original_copy_pointer->next;
581
582 // Create a new node and point position to it
583 this->position = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
584 // position->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
585
586 // Copy the item to the new node
587 // *(position->item)=*(original_copy_pointer->item);
588 this->position->item = original_copy_pointer->item;
589
590 if ( original_copy_pointer == original_copy.position )
591 save_position = this->position;
592
593 // Set the previous pointer for the new node
594 ( this->position->previous ) = last;
595
596 // Set the next pointer for the old node to the new node
597 ( last->next ) = this->position;
598
599 }
600
601 while ( ( original_copy_pointer->next ) != ( original_copy.root ) );
602
603 // 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
604 this->position->next = this->root;
605
606 this->root->previous = this->position;
607
608 this->list_size = original_copy.list_size;
609
610 this->position = save_position;
611 }
612 }
613
614 return true;
615 }
616
617 template <class CircularLinkedListType>
618 void CircularLinkedList<CircularLinkedListType>::Insert( const CircularLinkedListType& input )
619 {
620 node * new_node;
621
622 if ( list_size == 0 )
623 {
624 this->root = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
625 // root->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
626 //*(root->item)=input;
627 this->root->item = input;
628 this->root->next = this->root;
629 this->root->previous = this->root;
630 this->list_size = 1;
631 this->position = this->root;
632 }
633
634 else
635 if ( list_size == 1 )
636 {
637 this->position = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
638 // position->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
639 this->root->next = this->position;
640 this->root->previous = this->position;
641 this->position->previous = this->root;
642 this->position->next = this->root;
643 // *(position->item)=input;
644 this->position->item = input;
645 this->root = this->position; // Since we're inserting into a 1 element list the old root is now the second item
646 this->list_size = 2;
647 }
648
649 else
650 {
651 /*
652
653 B
654 |
655 A --- C
656
657 position->previous=A
658 new_node=B
659 position=C
660
661 Note that the order of the following statements is important */
662
663 new_node = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
664 // new_node->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
665
666 // *(new_node->item)=input;
667 new_node->item = input;
668
669 // Point next of A to B
670 ( this->position->previous ) ->next = new_node;
671
672 // Point last of B to A
673 new_node->previous = this->position->previous;
674
675 // Point last of C to B
676 this->position->previous = new_node;
677
678 // Point next of B to C
679 new_node->next = this->position;
680
681 // 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
682
683 if ( this->position == this->root )
684 {
685 this->root = new_node;
686 this->position = this->root;
687 }
688
689 // Increase the recorded size of the list by one
690 this->list_size++;
691 }
692 }
693
694 template <class CircularLinkedListType>
695 CircularLinkedListType& CircularLinkedList<CircularLinkedListType>::Add ( const CircularLinkedListType& input )
696 {
697 node * new_node;
698
699 if ( this->list_size == 0 )
700 {
701 this->root = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
702 // root->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
703 // *(root->item)=input;
704 this->root->item = input;
705 this->root->next = this->root;
706 this->root->previous = this->root;
707 this->list_size = 1;
708 this->position = this->root;
709 // return *(position->item);
710 return this->position->item;
711 }
712
713 else
714 if ( list_size == 1 )
715 {
716 this->position = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
717 // position->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
718 this->root->next = this->position;
719 this->root->previous = this->position;
720 this->position->previous = this->root;
721 this->position->next = this->root;
722 // *(position->item)=input;
723 this->position->item = input;
724 this->list_size = 2;
725 this->position = this->root; // Don't move the position from the root
726 // return *(position->item);
727 return this->position->item;
728 }
729
730 else
731 {
732 /*
733
734 B
735 |
736 A --- C
737
738 new_node=B
739 position=A
740 position->next=C
741
742 Note that the order of the following statements is important */
743
744 new_node = SLNet::OP_NEW<typename CircularLinkedList::node>( _FILE_AND_LINE_ );
745 // new_node->item = SLNet::OP_NEW<CircularLinkedListType>( _FILE_AND_LINE_ );
746
747 // *(new_node->item)=input;
748 new_node->item = input;
749
750 // Point last of B to A
751 new_node->previous = this->position;
752
753 // Point next of B to C
754 new_node->next = ( this->position->next );
755
756 // Point last of C to B
757 ( this->position->next ) ->previous = new_node;
758
759 // Point next of A to B
760 ( this->position->next ) = new_node;
761
762 // Increase the recorded size of the list by one
763 this->list_size++;
764
765 // return *(new_node->item);
766 return new_node->item;
767 }
768 }
769
770 template <class CircularLinkedListType>
771 inline void CircularLinkedList<CircularLinkedListType>::Replace( const CircularLinkedListType& input )
772 {
773 if ( this->list_size > 0 )
774 // *(position->item)=input;
775 this->position->item = input;
776 }
777
778 template <class CircularLinkedListType>
779 void CircularLinkedList<CircularLinkedListType>::Del()
780 {
781 node * new_position;
782
783 if ( this->list_size == 0 )
784 return ;
785
786 else
787 if ( this->list_size == 1 )
788 {
789 // SLNet::OP_DELETE(root->item, _FILE_AND_LINE_);
790 SLNet::OP_DELETE(this->root, _FILE_AND_LINE_);
791 this->root = this->position = 0;
792 this->list_size = 0;
793 }
794
795 else
796 {
797 ( this->position->previous ) ->next = this->position->next;
798 ( this->position->next ) ->previous = this->position->previous;
799 new_position = this->position->next;
800
801 if ( this->position == this->root )
802 this->root = new_position;
803
804 // SLNet::OP_DELETE(position->item, _FILE_AND_LINE_);
805 SLNet::OP_DELETE(this->position, _FILE_AND_LINE_);
806
807 this->position = new_position;
808
809 this->list_size--;
810 }
811 }
812
813 template <class CircularLinkedListType>
814 bool CircularLinkedList<CircularLinkedListType>::IsIn(const CircularLinkedListType& input )
815 {
816 node * return_value, *old_position;
817
818 old_position = this->position;
819
820 return_value = FindPointer( input );
821 this->position = old_position;
822
823 if ( return_value != 0 )
824 return true;
825 else
826 return false; // Can't find the item don't do anything
827 }
828
829 template <class CircularLinkedListType>
830 bool CircularLinkedList<CircularLinkedListType>::Find( const CircularLinkedListType& input )
831 {
832 node * return_value;
833
834 return_value = FindPointer( input );
835
836 if ( return_value != 0 )
837 {
838 this->position = return_value;
839 return true;
840 }
841
842 else
843 return false; // Can't find the item don't do anything
844 }
845
846 template <class CircularLinkedListType>
847 typename CircularLinkedList<CircularLinkedListType>::node* CircularLinkedList<CircularLinkedListType>::FindPointer( const CircularLinkedListType& input )
848 {
849 node * current;
850
851 if ( this->list_size == 0 )
852 return 0;
853
854 current = this->root;
855
856 // Search for the item starting from the root node and incrementing the pointer after every check
857 // 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
858 do
859 {
860 // if (*(current->item) == input) return current;
861
862 if ( current->item == input )
863 return current;
864
865 current = current->next;
866 }
867
868 while ( current != this->root );
869
870 return 0;
871
872 }
873
874 template <class CircularLinkedListType>
875 inline unsigned int CircularLinkedList<CircularLinkedListType>::Size( void )
876 {
877 return this->list_size;
878 }
879
880 template <class CircularLinkedListType>
881 inline CircularLinkedListType& CircularLinkedList<CircularLinkedListType>::Peek( void )
882 {
883 // return *(position->item);
884 return this->position->item;
885 }
886
887 template <class CircularLinkedListType>
888 CircularLinkedListType CircularLinkedList<CircularLinkedListType>::Pop( void )
889 {
890 CircularLinkedListType element;
891 element = Peek();
892 Del();
893 return CircularLinkedListType( element ); // return temporary
894 }
895
896 // Prefix
897 template <class CircularLinkedListType>
898 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator++()
899 {
900 if ( this->list_size != 0 )
901 position = position->next;
902
903 return *this;
904 }
905
906 /*
907 // Postfix
908 template <class CircularLinkedListType>
909 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator++(int)
910 {
911 CircularLinkedList<CircularLinkedListType> before;
912 before=*this;
913 operator++();
914 return before;
915 }
916 */
917
918 template <class CircularLinkedListType>
919 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator++( int )
920 {
921 return this->operator++();
922 }
923
924 // Prefix
925 template <class CircularLinkedListType>
926 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator--()
927 {
928 if ( this->list_size != 0 )
929 this->position = this->position->previous;
930
931 return *this;
932 }
933
934 /*
935 // Postfix
936 template <class CircularLinkedListType>
937 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator--(int)
938 {
939 CircularLinkedList<CircularLinkedListType> before;
940 before=*this;
941 operator--();
942 return before;
943 }
944 */
945
946 template <class CircularLinkedListType>
947 CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator--( int )
948 {
949 return this->operator--();
950 }
951
952 template <class CircularLinkedListType>
953 void CircularLinkedList<CircularLinkedListType>::Clear( void )
954 {
955 if ( this->list_size == 0 )
956 return ;
957 else
958 if ( this->list_size == 1 ) // {SLNet::OP_DELETE(root->item); SLNet::OP_DELETE(root, _FILE_AND_LINE_);}
959 {
960 SLNet::OP_DELETE(this->root, _FILE_AND_LINE_);
961 }
962
963 else
964 {
965 node* current;
966 node* temp;
967
968 current = this->root;
969
970 do
971 {
972 temp = current;
973 current = current->next;
974 // SLNet::OP_DELETE(temp->item, _FILE_AND_LINE_);
975 SLNet::OP_DELETE(temp, _FILE_AND_LINE_);
976 }
977
978 while ( current != this->root );
979 }
980
981 this->list_size = 0;
982 this->root = 0;
983 this->position = 0;
984 }
985
986 template <class CircularLinkedListType>
987 inline void CircularLinkedList<CircularLinkedListType>::Concatenate( const CircularLinkedList<CircularLinkedListType>& L )
988 {
989 unsigned int counter;
990 node* ptr;
991
992 if ( L.list_size == 0 )
993 return ;
994
995 if ( this->list_size == 0 )
996 * this = L;
997
998 ptr = L.root;
999
1000 this->position = this->root->previous;
1001
1002 // Cycle through each element in L and add it to the current list
1003 for ( counter = 0; counter < L.list_size; counter++ )
1004 {
1005 // Add item after the current item pointed to
1006 // add(*(ptr->item));
1007
1008 Add ( ptr->item );
1009
1010 // Update pointers. Moving ptr keeps the current pointer at the end of the list since the add function does not move the pointer
1011 ptr = ptr->next;
1012
1013 this->position = this->position->next;
1014 }
1015 }
1016
1017 template <class CircularLinkedListType>
1018 inline void CircularLinkedList<CircularLinkedListType>::Sort( void )
1019 {
1020 if ( this->list_size <= 1 )
1021 return ;
1022
1023 // Call equal operator to assign result of mergesort to current object
1024 *this = Mergesort( *this );
1025
1026 this->position = this->root;
1027 }
1028
1029 template <class CircularLinkedListType>
1030 CircularLinkedList<CircularLinkedListType> CircularLinkedList<CircularLinkedListType>::Mergesort( const CircularLinkedList& L )
1031 {
1032 unsigned int counter;
1033 node* location;
1034 CircularLinkedList<CircularLinkedListType> L1;
1035 CircularLinkedList<CircularLinkedListType> L2;
1036
1037 location = L.root;
1038
1039 // Split the list into two equal size sublists, L1 and L2
1040
1041 for ( counter = 0; counter < L.list_size / 2; counter++ )
1042 {
1043 // L1.add (*(location->item));
1044 L1.Add ( location->item );
1045 location = location->next;
1046 }
1047
1048 for ( ;counter < L.list_size; counter++ )
1049 {
1050 // L2.Add(*(location->item));
1051 L2.Add ( location->item );
1052 location = location->next;
1053 }
1054
1055 // Recursively sort the sublists
1056 if ( L1.list_size > 1 )
1057 L1 = Mergesort( L1 );
1058
1059 if ( L2.list_size > 1 )
1060 L2 = Mergesort( L2 );
1061
1062 // Merge the two sublists
1063 return Merge( L1, L2 );
1064 }
1065
1066 template <class CircularLinkedListType>
1067 CircularLinkedList<CircularLinkedListType> CircularLinkedList<CircularLinkedListType>::Merge( CircularLinkedList L1, CircularLinkedList L2 )
1068 {
1069 CircularLinkedList<CircularLinkedListType> X;
1070 CircularLinkedListType element;
1071 L1.position = L1.root;
1072 L2.position = L2.root;
1073
1074 // While neither list is empty
1075
1076 while ( ( L1.list_size != 0 ) && ( L2.list_size != 0 ) )
1077 {
1078 // Compare the first items of L1 and L2
1079 // Remove the smaller of the two items from the list
1080
1081 if ( ( ( L1.root ) ->item ) < ( ( L2.root ) ->item ) )
1082 // if ((*((L1.root)->item)) < (*((L2.root)->item)))
1083 {
1084 // element = *((L1.root)->item);
1085 element = ( L1.root ) ->item;
1086 L1.Del();
1087 }
1088 else
1089 {
1090 // element = *((L2.root)->item);
1091 element = ( L2.root ) ->item;
1092 L2.Del();
1093 }
1094
1095 // Add this item to the end of X
1096 X.Add( element );
1097
1098 X++;
1099 }
1100
1101 // Add the remaining list to X
1102 if ( L1.list_size != 0 )
1103 X.Concatenate( L1 );
1104 else
1105 X.Concatenate( L2 );
1106
1107 return X;
1108 }
1109
1110 template <class LinkedListType>
1111 LinkedList<LinkedListType> LinkedList<LinkedListType>::Mergesort( const LinkedList& L )
1112 {
1113 unsigned int counter;
1114 typename LinkedList::node* location;
1115 LinkedList<LinkedListType> L1;
1116 LinkedList<LinkedListType> L2;
1117
1118 location = L.root;
1119
1120 // Split the list into two equal size sublists, L1 and L2
1121
1122 for ( counter = 0; counter < L.LinkedList_size / 2; counter++ )
1123 {
1124 // L1.add (*(location->item));
1125 L1.Add ( location->item );
1126 location = location->next;
1127 }
1128
1129 for ( ;counter < L.LinkedList_size; counter++ )
1130 {
1131 // L2.Add(*(location->item));
1132 L2.Add ( location->item );
1133 location = location->next;
1134 }
1135
1136 // Recursively sort the sublists
1137 if ( L1.list_size > 1 )
1138 L1 = Mergesort( L1 );
1139
1140 if ( L2.list_size > 1 )
1141 L2 = Mergesort( L2 );
1142
1143 // Merge the two sublists
1144 return Merge( L1, L2 );
1145 }
1146
1147 template <class LinkedListType>
1148 LinkedList<LinkedListType> LinkedList<LinkedListType>::Merge( LinkedList L1, LinkedList L2 )
1149 {
1150 LinkedList<LinkedListType> X;
1151 LinkedListType element;
1152 L1.position = L1.root;
1153 L2.position = L2.root;
1154
1155 // While neither list is empty
1156
1157 while ( ( L1.LinkedList_size != 0 ) && ( L2.LinkedList_size != 0 ) )
1158 {
1159 // Compare the first items of L1 and L2
1160 // Remove the smaller of the two items from the list
1161
1162 if ( ( ( L1.root ) ->item ) < ( ( L2.root ) ->item ) )
1163 // if ((*((L1.root)->item)) < (*((L2.root)->item)))
1164 {
1165 element = ( L1.root ) ->item;
1166 // element = *((L1.root)->item);
1167 L1.Del();
1168 }
1169 else
1170 {
1171 element = ( L2.root ) ->item;
1172 // element = *((L2.root)->item);
1173 L2.Del();
1174 }
1175
1176 // Add this item to the end of X
1177 X.Add( element );
1178 }
1179
1180 // Add the remaining list to X
1181 if ( L1.LinkedList_size != 0 )
1182 X.concatenate( L1 );
1183 else
1184 X.concatenate( L2 );
1185
1186 return X;
1187 }
1188
1189
1190 // Prefix
1191 template <class LinkedListType>
1192 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator++()
1193 {
1194 if ( ( this->list_size != 0 ) && ( this->position->next != this->root ) )
1195 this->position = this->position->next;
1196
1197 return *this;
1198 }
1199
1200 /*
1201 // Postfix
1202 template <class LinkedListType>
1203 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator++(int)
1204 {
1205 LinkedList<LinkedListType> before;
1206 before=*this;
1207 operator++();
1208 return before;
1209 }
1210 */
1211 // Postfix
1212 template <class LinkedListType>
1213 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator++( int )
1214 {
1215 return this->operator++();
1216 }
1217
1218 // Prefix
1219 template <class LinkedListType>
1220 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator--()
1221 {
1222 if ( ( this->list_size != 0 ) && ( this->position != this->root ) )
1223 this->position = this->position->previous;
1224
1225 return *this;
1226 }
1227
1228 /*
1229 // Postfix
1230 template <class LinkedListType>
1231 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator--(int)
1232 {
1233 LinkedList<LinkedListType> before;
1234 before=*this;
1235 operator--();
1236 return before;
1237 }
1238 */
1239
1240 // Postfix
1241 template <class LinkedListType>
1242 LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator--( int )
1243 {
1244 return this->operator--();
1245 }
1246
1247 } // End namespace
1248
1249 #endif