00001 #ifndef PRIORITY_QUEUE_H
00002 #define PRIORITY_QUEUE_H
00003
00004 #include <Structs/Trees/completeBinaryTree.h>
00005 #include <limits>
00006
00007 typedef unsigned int PQSizeType;
00008
00009 template <typename KeyType, typename DataType>
00010 class HeapItem
00011 {
00012 public:
00013 typedef PQSizeType* DescriptorType;
00014
00015 HeapItem( unsigned int init = 0):key(std::numeric_limits<KeyType>::max()),data(),ptr()
00016 {
00017 }
00018 HeapItem( const KeyType& k, const DataType& d, const DescriptorType& p):key(k),data(d),ptr(p)
00019 {
00020 }
00021
00022 const KeyType& getKey() const
00023 {
00024 return key;
00025 }
00026
00027 const DataType& getData() const
00028 {
00029 return data;
00030 }
00031
00032 HeapItem operator = ( const HeapItem& other)
00033 {
00034 if( this != &other)
00035 {
00036 key = other.key;
00037 data = other.data;
00038 ptr = other.ptr;
00039 }
00040 return *this;
00041 }
00042
00043 void swapWith( HeapItem& other)
00044 {
00045 std::swap(this->key, other.key);
00046 std::swap(this->data, other.data);
00047 std::swap( (this->ptr), other.ptr);
00048 }
00049
00050 KeyType key;
00051 DataType data;
00052 DescriptorType ptr;
00053
00054
00055
00056 };
00057
00058
00059
00060
00061
00062
00063
00064
00065 template <typename KeyType, typename DataType, template <typename datatype> class StorageType>
00066 class PriorityQueue
00067 {
00068
00069 public:
00070 typedef PQSizeType SizeType;
00071 typedef PQSizeType* DescriptorType;
00072 typedef CompleteBinaryTree< HeapItem<KeyType,DataType>, StorageType> TreeType;
00073 typedef HeapItem<KeyType,DataType> PQItem;
00074 typedef typename TreeType::Node Node;
00075
00076 PriorityQueue():m_numItems(0)
00077 {
00078 m_auxNode = m_T.getRootNode();
00079 m_lastNode = m_T.getRootNode();
00080 }
00081
00082 ~PriorityQueue()
00083 {
00084 }
00085
00086 void clear()
00087 {
00088 while( !empty())
00089 popMin();
00090 }
00091
00092 bool contains( const DescriptorType ptr)
00093 {
00094 return ptr && ((*ptr) <= m_numItems);
00095 }
00096
00097 void decrease( const KeyType& key, const DescriptorType ptr)
00098 {
00099 if( ptr)
00100 {
00101 assert( (*ptr) <= m_numItems);
00102 m_auxNode.setAtBfsIndex( *ptr);
00103 m_auxNode->key = key;
00104 upheap(m_auxNode);
00105 }
00106 }
00107
00108 bool empty() const
00109 {
00110 return m_numItems == 0;
00111 }
00112
00120 void insert( const KeyType& key, const DataType& data, const DescriptorType ptr = 0)
00121 {
00122 increaseSize();
00123 m_auxNode.setAtBfsIndex( lastItemBfsIndex());
00124 m_auxNode->key = key;
00125 m_auxNode->data = data;
00126 m_auxNode->ptr = ptr;
00127 if( ptr)
00128 {
00129 *ptr = m_numItems;
00130 }
00131 upheap(m_auxNode);
00132 assert( *(m_auxNode->ptr) == m_auxNode.getBfsIndex() );
00133 }
00134
00135 const PQItem& min()
00136 {
00137 m_auxNode.setAtRoot();
00138 return *m_auxNode;
00139 }
00140
00141 const KeyType& minKey()
00142 {
00143 m_auxNode.setAtRoot();
00144 return m_auxNode->key;
00145 }
00146
00147 const DataType& minItem()
00148 {
00149 return min().data;
00150 }
00151
00152 void popMin()
00153 {
00154 assert( m_numItems > 0);
00155 m_auxNode.setAtRoot();
00156
00157 certainDownheap( m_auxNode);
00158 m_lastNode.setAtBfsIndex( lastItemBfsIndex() );
00159 if( m_auxNode != m_lastNode)
00160 {
00161 swap( m_auxNode, m_lastNode);
00162 upheap( m_auxNode);
00163 }
00164 *(m_lastNode->ptr) = std::numeric_limits<PQSizeType>::max();
00165 decreaseSize();
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175 void printGraphviz( const std::string& filename)
00176 {
00177 std::ofstream out( filename.c_str());
00178 out << "digraph BFS {\n\tedge [len=3]\n\tnode [fontname=\"Arial\"]\n";
00179
00180 std::stack<Node> S;
00181 m_auxNode.setAtRoot();
00182 S.push(m_auxNode);
00183 while( !S.empty())
00184 {
00185 m_auxNode = S.top();
00186 S.pop();
00187 out << m_auxNode.getPoolIndex();
00188 out << "[shape=record,label=\"{";
00189 out << m_auxNode.getBfsIndex() << "|";
00190 out << m_auxNode->key << "|";
00191 out << (m_auxNode->ptr);
00192 out << "}\"]\n";
00193 out << "\t";
00194 if( !m_auxNode.isLeaf())
00195 {
00196 out << m_auxNode.getPoolIndex();
00197 out << " -> ";
00198 m_auxNode.goLeft();
00199 out << m_auxNode.getPoolIndex();
00200 out << "\n";
00201 S.push(m_auxNode);
00202 m_auxNode.goUp();
00203 out << "\t";
00204 out << m_auxNode.getPoolIndex();
00205 out << " -> ";
00206 m_auxNode.goRight();
00207 out << m_auxNode.getPoolIndex();
00208 S.push(m_auxNode);
00209 }
00210 out << "\n";
00211 }
00212 out << "}";
00213 out.close();
00214 }
00215
00216
00217 const SizeType& size()
00218 {
00219 return m_numItems;
00220 }
00221
00222
00223 TreeType m_T;
00224
00225 private:
00226
00227 SizeType m_numItems;
00228 enum pos { PARENT, LEFT, RIGHT} m_minNodePos;
00229 KeyType m_minKey;
00230 Node m_auxNode, m_parentNode, m_lastNode, m_left, m_right;
00231 PQItem m_tempItem;
00232
00233 void certainDownheap( Node& u)
00234 {
00235 while( !u.isLeaf())
00236 {
00237 m_left = u;
00238 m_left.goLeft();
00239 m_right = u;
00240 m_right.goRight();
00241 if( !isInHeap( m_left)) return;
00242
00243 if( !isInHeap( m_right))
00244 {
00245 swap( u, m_left);
00246 u = m_left;
00247 return;
00248 }
00249
00250 if( m_left->key < m_right->key)
00251 {
00252 swap( u, m_left);
00253 u = m_left;
00254 }
00255 else
00256 {
00257 swap( u, m_right);
00258 u = m_right;
00259 }
00260 }
00261 }
00262
00263 void decreaseSize()
00264 {
00265 if( m_numItems < 9)
00266 {
00267 --m_numItems;
00268 return;
00269 }
00270
00271 if( isPowerOf2( m_numItems))
00272 {
00273 m_T.decreaseHeight();
00274 }
00275 --m_numItems;
00276 }
00277
00278 void downheap( Node& u)
00279 {
00280 while( !u.isLeaf())
00281 {
00282 m_minKey = u->key;
00283 m_minNodePos = PARENT;
00284 m_left = u;
00285 m_left.goLeft();
00286 if( isInHeap(m_left) && ( m_left->key < m_minKey) )
00287 {
00288 m_minKey = m_left->key;
00289 m_minNodePos = LEFT;
00290 }
00291
00292 m_right = u;
00293 m_right.goRight();
00294 if( isInHeap(m_right) && ( m_right->key < m_minKey) )
00295 {
00296 m_minKey = m_right->key;
00297 m_minNodePos = RIGHT;
00298 }
00299
00300 if( m_minNodePos == PARENT) return;
00301
00302 if( m_minNodePos == LEFT)
00303 {
00304 swap( u, m_left);
00305 u = m_left;
00306 }
00307 else
00308 {
00309 swap( u, m_right);
00310 u = m_right;
00311 }
00312 }
00313 }
00314
00315 void increaseSize()
00316 {
00317 ++m_numItems;
00318
00319
00320 if( m_numItems > m_T.getNumNodes())
00321 {
00322
00323 m_T.increaseHeight();
00324 }
00325 }
00326
00327 bool isInHeap( const Node& u) const
00328 {
00329 return u.getBfsIndex() <= lastItemBfsIndex();
00330 }
00331
00332 const SizeType& lastItemBfsIndex() const
00333 {
00334 return m_numItems;
00335 }
00336
00337 void swap( Node& u, Node& v)
00338 {
00339
00340
00341
00342
00343
00344
00345 u->swapWith(*v);
00346
00347 if( u->ptr) *(u->ptr) = u.getBfsIndex();
00348 if( v->ptr) *(v->ptr) = v.getBfsIndex();
00349
00350
00351
00352 }
00353
00354 void upheap( Node& u)
00355 {
00356 m_parentNode = u;
00357 while( !u.isRoot())
00358 {
00359 m_parentNode.goUp();
00360 if( m_parentNode->key > u->key)
00361 {
00362 swap( u, m_parentNode);
00363 u = m_parentNode;
00364 }
00365 else
00366 {
00367 return;
00368 }
00369 }
00370 }
00371
00372 };
00373
00374
00375 #endif //PRIORITY_QUEUE_H