00001 /* 00002 00003 ************************************************************************* 00004 00005 ArmageTron -- Just another Tron Lightcycle Game in 3D. 00006 Copyright (C) 2000 Manuel Moos (manuel@moosnet.de) 00007 00008 ************************************************************************** 00009 00010 This program is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU General Public License 00012 as published by the Free Software Foundation; either version 2 00013 of the License, or (at your option) any later version. 00014 00015 This program is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 along with this program; if not, write to the Free Software 00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00023 00024 *************************************************************************** 00025 00026 */ 00027 00028 #include "tLinkedList.h" 00029 00030 void tListItemBase::Remove(){ 00031 if (anchor){ 00032 *anchor = next; 00033 if (next) 00034 next->anchor = anchor; 00035 anchor = NULL; 00036 next = NULL; 00037 } 00038 } 00039 00040 void tListItemBase::Insert(tListItemBase *&a){ 00041 if (anchor) 00042 Remove(); 00043 anchor = &a; 00044 next = a; 00045 a = this; 00046 if (next) 00047 next->anchor = &next; 00048 } 00049 00050 int tListItemBase::Len(){ 00051 int ret=0; 00052 tListItemBase* x=this; 00053 while (x){ 00054 ret++; 00055 x = x->next; 00056 } 00057 return ret; 00058 } 00059 00060 void tListItemBase::Sort( Comparator* compare ) 00061 { 00062 // early return statements: empty list or single element in list 00063 if ( !this || !next ) 00064 { 00065 return; 00066 } 00067 00068 tListItemBase* middle = this; 00069 { 00070 // locate the middle of the list 00071 tListItemBase* run = *anchor; 00072 while ( run ) 00073 { 00074 middle = middle->next; 00075 run = run->next; 00076 if ( run ) 00077 { 00078 run = run->next; 00079 } 00080 } 00081 } 00082 00083 // split the list in the middle 00084 *middle->anchor = NULL; 00085 middle->anchor = &middle; 00086 00087 // retrieve the anchor of the first half list 00088 tListItemBase*& first = *anchor; 00089 00090 // sort the two half lists 00091 first->Sort( compare ); 00092 middle->Sort( compare ); 00093 00094 // merge the lists 00095 { 00096 tListItemBase** run = &first; 00097 while ( middle ) 00098 { 00099 // find the correct place for middle 00100 while ( *run && compare( *run, middle ) > 0 ) 00101 run = &(*run)->next; 00102 00103 // remove middle from the second list; care needs to be taken because middle->remove() would modify middle. 00104 tListItemBase* insert = middle; 00105 insert->Remove(); 00106 00107 // insert it into the first list 00108 insert->Insert( *run ); 00109 run = &insert->next; 00110 } 00111 } 00112 00113 // done! 00114 } 00115