00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _DECAF_UTIL_PRIORITYQUEUE_H_
00019 #define _DECAF_UTIL_PRIORITYQUEUE_H_
00020
00021 #include <decaf/util/Config.h>
00022 #include <decaf/util/Collection.h>
00023 #include <decaf/util/AbstractQueue.h>
00024 #include <decaf/util/Iterator.h>
00025 #include <decaf/util/Comparator.h>
00026 #include <decaf/util/comparators/Less.h>
00027
00028 #include <decaf/lang/Math.h>
00029 #include <decaf/lang/Pointer.h>
00030 #include <decaf/lang/exceptions/NullPointerException.h>
00031 #include <decaf/lang/exceptions/UnsupportedOperationException.h>
00032
00033 #include <memory>
00034
00035 namespace decaf {
00036 namespace util {
00037
00038 class DECAF_API PriorityQueueBase {
00039 protected:
00040
00041 static const int DEFAULT_CAPACITY;
00042 static const int DEFAULT_CAPACITY_RATIO;
00043
00044 virtual ~PriorityQueueBase() {}
00045 };
00046
00077 template< typename E >
00078 class PriorityQueue : public AbstractQueue<E>, private PriorityQueueBase {
00079 private:
00080
00081 int _size;
00082 int capacity;
00083 E* elements;
00084 decaf::lang::Pointer< Comparator<E> > _comparator;
00085
00086 private:
00087
00088 class PriorityQueueIterator : public Iterator<E> {
00089 private:
00090
00091 PriorityQueueIterator( const PriorityQueueIterator& );
00092 PriorityQueueIterator& operator= ( const PriorityQueueIterator& );
00093
00094 private:
00095
00096 int position;
00097 bool allowRemove;
00098 PriorityQueue* queue;
00099
00100 public:
00101
00102 PriorityQueueIterator( PriorityQueue* queue ) : position( 0 ), allowRemove( false ), queue( queue ) {}
00103
00104 virtual E next() {
00105
00106 if( !hasNext() ) {
00107 throw NoSuchElementException(
00108 __FILE__, __LINE__,
00109 "No more elements to Iterate over." );
00110 }
00111
00112 allowRemove = true;
00113 return queue->elements[position++];
00114 }
00115
00116 virtual bool hasNext() const {
00117 return position < queue->_size;
00118 }
00119
00120 virtual void remove() {
00121
00122 if( !allowRemove ) {
00123 throw lang::exceptions::IllegalStateException(
00124 __FILE__, __LINE__,
00125 "No more elements to Iterate over." );
00126 }
00127
00128 allowRemove = false;
00129 queue->removeAt( position-- );
00130 }
00131 };
00132
00133 class ConstPriorityQueueIterator : public PriorityQueueIterator {
00134 private:
00135
00136 ConstPriorityQueueIterator( const ConstPriorityQueueIterator& );
00137 ConstPriorityQueueIterator& operator= ( const ConstPriorityQueueIterator& );
00138
00139 public:
00140
00141 ConstPriorityQueueIterator( const PriorityQueue* queue ) :
00142 PriorityQueueIterator( const_cast<PriorityQueue*>( queue ) ) {}
00143
00144 virtual void remove() {
00145 throw lang::exceptions::UnsupportedOperationException(
00146 __FILE__, __LINE__,
00147 "PriorityQueue::Iterator::remove - Not Valid on a Const Iterator" );
00148 }
00149 };
00150
00151 friend class PriorityQueueIterator;
00152
00153 public:
00154
00158 PriorityQueue() : AbstractQueue<E>(), _size( 0 ), capacity( 0 ), elements( NULL ), _comparator() {
00159 this->initQueue( DEFAULT_CAPACITY, new comparators::Less<E>() );
00160 }
00161
00168 PriorityQueue( int initialCapacity ) :
00169 AbstractQueue<E>(), _size( 0 ), capacity( 0 ), elements( NULL ), _comparator() {
00170
00171 this->initQueue( initialCapacity, new comparators::Less<E>() );
00172 }
00173
00186 PriorityQueue( int initialCapacity, Comparator<E>* comparator ) :
00187 AbstractQueue<E>(), _size( 0 ), capacity( 0 ), elements( NULL ), _comparator() {
00188
00189 if( comparator == NULL ) {
00190 throw decaf::lang::exceptions::NullPointerException(
00191 __FILE__, __LINE__, "Passed Comparator Cannot be NULL." );
00192 }
00193
00194 this->initQueue( initialCapacity, comparator );
00195 }
00196
00203 PriorityQueue( const Collection<E>& source ) :
00204 AbstractQueue<E>(), _size( 0 ), capacity( 0 ), elements( NULL ), _comparator() {
00205
00206 this->getFromCollection( source );
00207 }
00208
00216 PriorityQueue( const PriorityQueue<E>& source ) :
00217 AbstractQueue<E>(), _size( 0 ), capacity( 0 ), elements( NULL ), _comparator() {
00218
00219 this->getFromPriorityQueue( source );
00220 }
00221
00222 virtual ~PriorityQueue() {
00223 delete [] elements;
00224 }
00225
00232 PriorityQueue<E>& operator= ( const Collection<E>& source ) {
00233 this->getFromCollection( source );
00234 return *this;
00235 }
00236
00243 PriorityQueue<E>& operator= ( const PriorityQueue<E>& source ) {
00244 this->getFromPriorityQueue( source );
00245 return *this;
00246 }
00247
00248 public:
00249
00250 virtual decaf::util::Iterator<E>* iterator() {
00251 return new PriorityQueueIterator( this );
00252 }
00253
00254 virtual decaf::util::Iterator<E>* iterator() const {
00255 return new ConstPriorityQueueIterator( this );
00256 }
00257
00258 virtual int size() const {
00259 return this->_size;
00260 }
00261
00262 virtual void clear() {
00263
00264
00265
00266
00267
00268 delete [] this->elements;
00269
00270 this->elements = new E[DEFAULT_CAPACITY];
00271 this->capacity = DEFAULT_CAPACITY;
00272 this->_size = 0;
00273 }
00274
00275 virtual bool offer( const E& value ) {
00276
00277
00278
00279 increaseCapacity( _size + 1 );
00280 elements[_size++] = value;
00281 upHeap();
00282 return true;
00283 }
00284
00285 virtual bool poll( E& result ) {
00286
00287 if( this->isEmpty() ) {
00288 return false;
00289 }
00290
00291 result = elements[0];
00292 removeAt( 0 );
00293 return true;
00294 }
00295
00296 virtual bool peek( E& result ) const {
00297
00298 if( this->isEmpty() ) {
00299 return false;
00300 }
00301
00302 result = elements[0];
00303 return true;
00304 }
00305
00306 virtual E remove() {
00307
00308 if( !this->isEmpty() ) {
00309 E result = elements[0];
00310 removeAt( 0 );
00311 return result;
00312 }
00313
00314 throw decaf::util::NoSuchElementException(
00315 __FILE__, __LINE__, "Unable to remove specified element from the Queue." );
00316 }
00317
00318 virtual bool remove( const E& value ) {
00319
00320 int targetIndex = 0;
00321 for( targetIndex = 0; targetIndex < _size; targetIndex++ ) {
00322 if( 0 == _comparator->compare( value, elements[targetIndex] ) ) {
00323 break;
00324 }
00325 }
00326
00327 if( _size == 0 || _size == targetIndex ) {
00328 return false;
00329 }
00330
00331 removeAt( targetIndex );
00332 return true;
00333 }
00334
00335 virtual bool add( const E& value ) {
00336
00337 try {
00338 return offer( value );
00339 }
00340 DECAF_CATCH_RETHROW( lang::exceptions::UnsupportedOperationException )
00341 DECAF_CATCH_RETHROW( lang::exceptions::IllegalArgumentException )
00342 DECAF_CATCH_RETHROW( lang::exceptions::IllegalStateException )
00343 DECAF_CATCH_EXCEPTION_CONVERT( lang::exceptions::NullPointerException, lang::exceptions::UnsupportedOperationException )
00344 DECAF_CATCHALL_THROW( lang::exceptions::UnsupportedOperationException )
00345 }
00346
00354 decaf::lang::Pointer< Comparator<E> > comparator() const {
00355 return this->_comparator;
00356 }
00357
00358 private:
00359
00360 void initQueue( int initialSize, Comparator<E>* comparator ) {
00361 this->elements = new E[initialSize];
00362 this->capacity = initialSize;
00363 this->_size = 0;
00364 this->_comparator.reset( comparator );
00365 }
00366
00367 void upHeap() {
00368
00369 int current = _size - 1;
00370 int parent = ( current - 1 ) / 2;
00371
00372 while( current != 0 && _comparator->compare( elements[current], elements[parent] ) < 0 ) {
00373
00374
00375 E tmp = elements[current];
00376 elements[current] = elements[parent];
00377 elements[parent] = tmp;
00378
00379
00380 current = parent;
00381 parent = ( current - 1 ) / 2;
00382 }
00383 }
00384
00385 void downHeap( int pos ) {
00386
00387 int current = pos;
00388 int child = 2 * current + 1;
00389
00390 while( child < _size && !this->isEmpty() ) {
00391
00392
00393 if( child + 1 < _size && _comparator->compare( elements[child + 1], elements[child] ) < 0 ) {
00394 child++;
00395 }
00396
00397
00398 if( _comparator->compare( elements[current], elements[child] ) < 0 ) {
00399 break;
00400 }
00401
00402
00403 E tmp = elements[current];
00404 elements[current] = elements[child];
00405 elements[child] = tmp;
00406
00407
00408 current = child;
00409 child = 2 * current + 1;
00410 }
00411 }
00412
00413 void getFromPriorityQueue( const PriorityQueue<E>& c ) {
00414 initCapacity( c );
00415 _comparator = c.comparator();
00416 for( int ix = 0; ix < c.size(); ++ix ) {
00417 this->elements[ix] = c.elements[ix];
00418 }
00419 _size = c.size();
00420 }
00421
00422 void getFromCollection( const Collection<E>& c ) {
00423 initCapacity( c );
00424 _comparator.reset( new comparators::Less<E>() );
00425 std::auto_ptr< Iterator<E> > iter( c.iterator() );
00426 while( iter->hasNext() ) {
00427 this->offer( iter->next() );
00428 }
00429 }
00430
00431 void removeAt( int index ) {
00432 _size--;
00433 elements[index] = elements[_size];
00434 downHeap(index);
00435 elements[_size] = E();
00436 }
00437
00438 void initCapacity( const Collection<E>& c ) {
00439
00440 delete [] elements;
00441 _size = 0;
00442
00443 if( c.isEmpty() ) {
00444 capacity = 1;
00445 elements = new E[capacity];
00446 } else {
00447 capacity = (int) lang::Math::ceil( (double)c.size() * 1.1 );
00448 elements = new E[capacity];
00449 }
00450 }
00451
00452 void increaseCapacity( int size ) {
00453
00454 if( size > capacity ) {
00455 E* newElements = new E[ size * DEFAULT_CAPACITY_RATIO ];
00456
00457 for( int ix = 0; ix < capacity; ix++ ) {
00458 newElements[ix] = elements[ix];
00459 }
00460
00461 delete [] elements;
00462
00463 elements = newElements;
00464 capacity = size * DEFAULT_CAPACITY_RATIO;
00465 }
00466 }
00467
00468 };
00469
00470 }}
00471
00472 #endif