src/tools/tHeap.cpp

Go to the documentation of this file.
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 "tHeap.h"
00029 #include "tConsole.h"
00030 #include <iostream>
00031 
00032 /* ************************
00033    Heap data structure
00034    ************************ */
00035 
00036 
00037 bool tHeapBase::SwapIf(int i,int j)
00038 {
00039     if (i==j || i<0) return false; // safety
00040 
00041     tHeapElement *e1=operator()(i),*e2=operator()(j);
00042 
00043     tASSERT( e1->hID == i );
00044     tASSERT( e2->hID == j );
00045 
00046     if (e1->Val() > e2->Val()){
00047         Swap(tList< tHeapElement >::operator()(i),tList< tHeapElement >::operator()(j));
00048         e1->hID=j;
00049         e2->hID=i;
00050         return true;
00051     }
00052     else
00053         return false;
00054 }
00055 
00056 tHeapBase::~tHeapBase()
00057 {
00058     while(Len() > 0)
00059         Remove(0);
00060 }
00061 
00062 //#ifdef EVENT_DEB
00063 void tHeapBase::CheckHeap(){
00064     for(int i=Len()-1;i>0;i--){
00065         tHeapElement *current=operator()(i);
00066         tHeapElement *low=operator()(Lower(i));
00067         if (Lower(UpperL(i))!=i || Lower(UpperR(i))!=i)
00068             tERR_ERROR_INT("Error in lower/upper " << i << "!");
00069 
00070         if (low->Val() > current->Val() )
00071             tERR_ERROR_INT("Heap structure corrupt!");
00072 
00073         if ( current->hID != i )
00074             tERR_ERROR_INT("Heap list structure corrupt!");
00075     }
00076 }
00077 //#endif
00078 
00079 void tHeapBase::SwapDown(int j){
00080     int i=j;
00081     // e is now at position i. swap it down
00082     // as far as it goes:
00083     do{
00084         j=i;
00085         i=Lower(j);
00086     }
00087     while(SwapIf(i,j)); // mean: relies on the fact that SwapIf returns -1
00088     // if i<0.
00089 
00090 #ifdef EVENT_DEB
00091     CheckHeap();
00092 #endif
00093 }
00094 
00095 void tHeapBase::SwapUp(int i){
00096 #ifdef EVENT_DEB
00097     //  static int su=0;
00098     //  if (su%100 ==0 )
00099     //    con << "su=" << su << '\n';
00100     //  if (su > 11594 )
00101     // con << "su=" << su << '\n';
00102     //  su ++;
00103 #endif
00104 
00105     int ul,ur;
00106     bool goon=1;
00107     while(goon && UpperL(i)<Len()){
00108         ul=UpperL(i);
00109         ur=UpperR(i);
00110         if(ur>=Len() ||
00111                 operator()(ul)->Val() < operator()(ur)->Val() ){
00112             goon=SwapIf(i,ul);
00113             i=ul;
00114         }
00115         else{
00116             goon=SwapIf(i,ur);
00117             i=ur;
00118         }
00119     }
00120 
00121 #ifdef EVENT_DEB
00122     CheckHeap();
00123 #endif
00124 
00125 }
00126 
00127 void tHeapBase::Insert(tHeapElement *e){
00128 #ifdef EVENT_DEB
00129     CheckHeap();
00130 #endif
00131 
00132     Add(e,e->hID); // relies on the implementation of List: e is
00133     // put to the back of the heap.
00134     tASSERT(e->hID == Len()-1);
00135     SwapDown(Len()-1);  // bring it to the right place
00136 
00137 #ifdef EVENT_DEB
00138     CheckHeap();
00139 #endif
00140 }
00141 
00142 void tHeapBase::Remove(tHeapElement *e){
00143     int i=e->hID;
00144 
00145 #ifdef EVENT_DEB
00146     CheckHeap();
00147 #endif
00148 
00149     // element
00150     if(i<0 )
00151     {
00152 #ifdef DEBUG
00153         static bool warn = true;
00154         if ( warn )
00155         {
00156             tERR_WARN("Element to be removed from heap was already removed. Unless there is a fatal exit in process, this is not right.");
00157             warn=false;
00158         }
00159 #endif
00160         return;
00161     }
00162 
00163     if( this != e->Heap())
00164         tERR_ERROR_INT("Element is not in this heap! (Note: this usually is a followup error when the system fails to recover from another error. When reporting, please also include whatever happened before this.)");
00165 
00166     Remove(i);
00167 
00168 #ifdef EVENT_DEB
00169     CheckHeap();
00170 #endif
00171 }
00172 
00173 void tHeapBase::Replace(int i){
00174     if (i>=0 && i < Len()){
00175         if (i==0 || operator()(i)->Val() > operator()(Lower(i))->Val() )
00176             SwapUp(i);          // put it up where it belongs
00177         else
00178             SwapDown(i);
00179 
00180 #ifdef EVENT_DEB
00181         CheckHeap();
00182 #endif
00183     }
00184 }
00185 
00186 void tHeapBase::Replace(tHeapElement *e){
00187     int i=e->hID;
00188 
00189     if(i<0 || this != e->Heap())
00190         tERR_ERROR_INT("Element is not in this heap! (Note: this usually is a followup error when the system fails to recover from another error. When reporting, please also include whatever happened before this.)");
00191 
00192     Replace(i);
00193 
00194 #ifdef EVENT_DEB
00195     CheckHeap();
00196 #endif
00197 }
00198 
00199 tHeapElement * tHeapBase::Remove(int i){
00200 #ifdef EVENT_DEB
00201     CheckHeap();
00202 #endif
00203 
00204     if (i>=0 && i<Len())
00205     {
00206         tHeapElement *ret=operator()(i);
00207 
00208         tASSERT( ret->hID == i );
00209 
00210         tList<tHeapElement>::Remove(ret,ret->hID);
00211 
00212         // now we have an misplaced element at pos i. (if i was not at the end..)
00213         if (i<Len())
00214             Replace(i);
00215 
00216 #ifdef EVENT_DEB
00217         CheckHeap();
00218 #endif
00219 
00220         return ret;
00221     }
00222     return NULL;
00223 }
00224 
00225 
00226 
00227 /* ************************
00228    Events:
00229    ************************ */
00230 
00231 tHeapElement::~tHeapElement()
00232 {
00233     tASSERT( hID < 0 );
00234 }
00235 
00236 void tHeapElement::RemoveFromHeap(){
00237     tASSERT( this );
00238 
00239     if (hID>=0)
00240     {
00241         tASSERT( Heap() );
00242         Heap()->Remove(this);
00243     }
00244 }
00245 
00246 void tHeapElement::SetVal( REAL value, tHeapBase& heap )
00247 {
00248     tASSERT( !Heap() || Heap() == &heap );
00249 
00250     this->value_ = value;
00251 
00252     if ( hID>=0 )
00253     {
00254         tASSERT( heap( hID ) == this );
00255 
00256         heap.Replace( this );
00257     }
00258     else
00259     {
00260         heap.Insert( this );
00261     }
00262 }
00263 
00264 // in wich heap are we?
00265 tHeapBase *tHeapElement::Heap() const
00266 {
00267     tASSERT( 0 );
00268     return NULL;
00269 }
00270 
00271 

Generated on Sat Mar 15 22:56:00 2008 for Armagetron Advanced by  doxygen 1.5.4