00001
00019 #include "fxuInt.h"
00020
00024
00025 #define FXU_HEAP_SINGLE_WEIGHT(pSingle) ((pSingle)->Weight)
00026 #define FXU_HEAP_SINGLE_CURRENT(p, pSingle) ((p)->pTree[(pSingle)->HNum])
00027 #define FXU_HEAP_SINGLE_PARENT_EXISTS(p, pSingle) ((pSingle)->HNum > 1)
00028 #define FXU_HEAP_SINGLE_CHILD1_EXISTS(p, pSingle) (((pSingle)->HNum << 1) <= p->nItems)
00029 #define FXU_HEAP_SINGLE_CHILD2_EXISTS(p, pSingle) ((((pSingle)->HNum << 1)+1) <= p->nItems)
00030 #define FXU_HEAP_SINGLE_PARENT(p, pSingle) ((p)->pTree[(pSingle)->HNum >> 1])
00031 #define FXU_HEAP_SINGLE_CHILD1(p, pSingle) ((p)->pTree[(pSingle)->HNum << 1])
00032 #define FXU_HEAP_SINGLE_CHILD2(p, pSingle) ((p)->pTree[((pSingle)->HNum << 1)+1])
00033 #define FXU_HEAP_SINGLE_ASSERT(p, pSingle) assert( (pSingle)->HNum >= 1 && (pSingle)->HNum <= p->nItemsAlloc )
00034
00035 static void Fxu_HeapSingleResize( Fxu_HeapSingle * p );
00036 static void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 );
00037 static void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle );
00038 static void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle );
00039
00043
00055 Fxu_HeapSingle * Fxu_HeapSingleStart()
00056 {
00057 Fxu_HeapSingle * p;
00058 p = ALLOC( Fxu_HeapSingle, 1 );
00059 memset( p, 0, sizeof(Fxu_HeapSingle) );
00060 p->nItems = 0;
00061 p->nItemsAlloc = 2000;
00062 p->pTree = ALLOC( Fxu_Single *, p->nItemsAlloc + 10 );
00063 p->pTree[0] = NULL;
00064 return p;
00065 }
00066
00067
00079 void Fxu_HeapSingleResize( Fxu_HeapSingle * p )
00080 {
00081 p->nItemsAlloc *= 2;
00082 p->pTree = REALLOC( Fxu_Single *, p->pTree, p->nItemsAlloc + 10 );
00083 }
00084
00096 void Fxu_HeapSingleStop( Fxu_HeapSingle * p )
00097 {
00098 int i;
00099 i = 0;
00100 free( p->pTree );
00101 i = 1;
00102 free( p );
00103 }
00104
00105
00117 void Fxu_HeapSinglePrint( FILE * pFile, Fxu_HeapSingle * p )
00118 {
00119 Fxu_Single * pSingle;
00120 int Counter = 1;
00121 int Degree = 1;
00122
00123 Fxu_HeapSingleCheck( p );
00124 fprintf( pFile, "The contents of the heap:\n" );
00125 fprintf( pFile, "Level %d: ", Degree );
00126 Fxu_HeapSingleForEachItem( p, pSingle )
00127 {
00128 assert( Counter == p->pTree[Counter]->HNum );
00129 fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_SINGLE_WEIGHT(p->pTree[Counter]) );
00130 if ( ++Counter == (1 << Degree) )
00131 {
00132 fprintf( pFile, "\n" );
00133 Degree++;
00134 fprintf( pFile, "Level %d: ", Degree );
00135 }
00136 }
00137 fprintf( pFile, "\n" );
00138 fprintf( pFile, "End of the heap printout.\n" );
00139 }
00140
00152 void Fxu_HeapSingleCheck( Fxu_HeapSingle * p )
00153 {
00154 Fxu_Single * pSingle;
00155 Fxu_HeapSingleForEachItem( p, pSingle )
00156 {
00157 assert( pSingle->HNum == p->i );
00158 Fxu_HeapSingleCheckOne( p, pSingle );
00159 }
00160 }
00161
00173 void Fxu_HeapSingleCheckOne( Fxu_HeapSingle * p, Fxu_Single * pSingle )
00174 {
00175 int Weight1, Weight2;
00176 if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) )
00177 {
00178 Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle);
00179 Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) );
00180 assert( Weight1 >= Weight2 );
00181 }
00182 if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) )
00183 {
00184 Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle);
00185 Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) );
00186 assert( Weight1 >= Weight2 );
00187 }
00188 }
00189
00201 void Fxu_HeapSingleInsert( Fxu_HeapSingle * p, Fxu_Single * pSingle )
00202 {
00203 if ( p->nItems == p->nItemsAlloc )
00204 Fxu_HeapSingleResize( p );
00205
00206 p->pTree[++p->nItems] = pSingle;
00207 pSingle->HNum = p->nItems;
00208
00209 Fxu_HeapSingleMoveUp( p, pSingle );
00210 }
00211
00223 void Fxu_HeapSingleUpdate( Fxu_HeapSingle * p, Fxu_Single * pSingle )
00224 {
00225 FXU_HEAP_SINGLE_ASSERT(p,pSingle);
00226 if ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,pSingle) &&
00227 FXU_HEAP_SINGLE_WEIGHT(pSingle) > FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_PARENT(p,pSingle) ) )
00228 Fxu_HeapSingleMoveUp( p, pSingle );
00229 else if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) &&
00230 FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) ) )
00231 Fxu_HeapSingleMoveDn( p, pSingle );
00232 else if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) &&
00233 FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) ) )
00234 Fxu_HeapSingleMoveDn( p, pSingle );
00235 }
00236
00248 void Fxu_HeapSingleDelete( Fxu_HeapSingle * p, Fxu_Single * pSingle )
00249 {
00250 int Place = pSingle->HNum;
00251 FXU_HEAP_SINGLE_ASSERT(p,pSingle);
00252
00253
00254 p->pTree[Place] = p->pTree[p->nItems--];
00255 p->pTree[Place]->HNum = Place;
00256
00257 Fxu_HeapSingleUpdate( p, p->pTree[Place] );
00258 pSingle->HNum = 0;
00259 }
00260
00272 Fxu_Single * Fxu_HeapSingleReadMax( Fxu_HeapSingle * p )
00273 {
00274 if ( p->nItems == 0 )
00275 return NULL;
00276 return p->pTree[1];
00277 }
00278
00290 Fxu_Single * Fxu_HeapSingleGetMax( Fxu_HeapSingle * p )
00291 {
00292 Fxu_Single * pSingle;
00293 if ( p->nItems == 0 )
00294 return NULL;
00295
00296 pSingle = p->pTree[1];
00297 pSingle->HNum = 0;
00298
00299
00300 p->pTree[1] = p->pTree[p->nItems--];
00301 p->pTree[1]->HNum = 1;
00302
00303 Fxu_HeapSingleMoveDn( p, p->pTree[1] );
00304 return pSingle;
00305 }
00306
00318 int Fxu_HeapSingleReadMaxWeight( Fxu_HeapSingle * p )
00319 {
00320 if ( p->nItems == 0 )
00321 return -1;
00322 return FXU_HEAP_SINGLE_WEIGHT(p->pTree[1]);
00323 }
00324
00325
00326
00338 void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 )
00339 {
00340 Fxu_Single * pSingle;
00341 int Temp;
00342 pSingle = *pSingle1;
00343 *pSingle1 = *pSingle2;
00344 *pSingle2 = pSingle;
00345 Temp = (*pSingle1)->HNum;
00346 (*pSingle1)->HNum = (*pSingle2)->HNum;
00347 (*pSingle2)->HNum = Temp;
00348 }
00349
00361 void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle )
00362 {
00363 Fxu_Single ** ppSingle, ** ppPar;
00364 ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle);
00365 while ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,*ppSingle) )
00366 {
00367 ppPar = &FXU_HEAP_SINGLE_PARENT(p,*ppSingle);
00368 if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) > FXU_HEAP_SINGLE_WEIGHT(*ppPar) )
00369 {
00370 Fxu_HeapSingleSwap( ppSingle, ppPar );
00371 ppSingle = ppPar;
00372 }
00373 else
00374 break;
00375 }
00376 }
00377
00389 void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle )
00390 {
00391 Fxu_Single ** ppChild1, ** ppChild2, ** ppSingle;
00392 ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle);
00393 while ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,*ppSingle) )
00394 {
00395
00396
00397 ppChild1 = &FXU_HEAP_SINGLE_CHILD1(p,*ppSingle);
00398 if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,*ppSingle) )
00399 {
00400 ppChild2 = &FXU_HEAP_SINGLE_CHILD2(p,*ppSingle);
00401
00402
00403 if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) &&
00404 FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) )
00405 {
00406 break;
00407 }
00408 else
00409 {
00410 if ( FXU_HEAP_SINGLE_WEIGHT(*ppChild1) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) )
00411 {
00412 Fxu_HeapSingleSwap( ppSingle, ppChild1 );
00413
00414 ppSingle = ppChild1;
00415 }
00416 else
00417 {
00418 Fxu_HeapSingleSwap( ppSingle, ppChild2 );
00419
00420 ppSingle = ppChild2;
00421 }
00422 }
00423 }
00424 else
00425 {
00426
00427 if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) )
00428 {
00429 break;
00430 }
00431 else
00432 {
00433 Fxu_HeapSingleSwap( ppSingle, ppChild1 );
00434
00435 ppSingle = ppChild1;
00436 }
00437 }
00438 }
00439 }
00440
00441