Open
Graph Drawing
Framework

 v.2012.05
 

MinPriorityQueue.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008  
00043 #ifdef _MSC_VER
00044 #pragma once
00045 #endif
00046 
00047 
00048 
00049 #ifndef MINPRIORITYQUEUE_H_
00050 #define MINPRIORITYQUEUE_H_
00051 
00052 #include<ogdf/basic/Array.h>
00053 
00054 
00055 namespace ogdf {
00056 
00057 
00058 template<class Score, class X> 
00059 class HeapElement { 
00060     
00061     template<class T1, class T2> friend class MinPriorityQueue;
00062     
00063     private:    
00064         Score v;
00065         X x;
00066         int pos; // the position in the heapElement array
00067     public: 
00068         HeapElement(){}
00069         //copy constructor
00070         HeapElement(const HeapElement<Score, X> &orig): v(orig.v), x(orig.x), pos(orig.pos) {} 
00071         HeapElement(Score vt, X xt) : v(vt), x(xt) {}           
00072         
00073         //return the score
00074         Score score_value() const { return v; }
00075         // return the element
00076         X element() const { return x;}      
00077 };
00078 
00079 
00080 
00081 // using min heaps
00082 // follow the pseudo code of "introduction to algorithms" 
00083 template <class Score, class X> 
00084 class MinPriorityQueue {
00085     
00086     private :
00087     
00088     HeapElement<Score, X> **heapElements; 
00089         
00090     int number; // the number of elements in the Queue  
00091     int s; // size
00092     
00093     void swap(int pos1, int pos2) {
00094         HeapElement<Score, X> *tmp = heapElements[pos1];
00095         heapElements[pos1] = heapElements[pos2];
00096         heapElements[pos2] = tmp;
00097         // update the position
00098         heapElements[pos2]->pos = pos2;
00099         heapElements[pos1]->pos = pos1;
00100     } 
00101     
00102     void minHeapify(int pos) {
00103         int l = getLeft(pos);
00104         int r = getRight(pos);
00105         int smallest;
00106         if (l <= number && heapElements[l]->score_value() < heapElements[pos]->score_value() )
00107             smallest = l;
00108         else
00109             smallest = pos;
00110         if (r <= number && heapElements[r]->score_value() < heapElements[smallest]->score_value())
00111             smallest = r;
00112         if (smallest != pos) {
00113             swap(pos, smallest);
00114             minHeapify(smallest);
00115         } 
00116     }
00117     
00118     int getParent(int pos) const {return pos/2;}
00119     int getLeft(int pos) const {return pos*2;}
00120     int getRight(int pos) const {return pos*2+1;}   
00121     
00122     
00123     public:
00124     
00125     // contructor, only fixed size
00126     MinPriorityQueue(int _size) : number(0), s(_size) {
00127         heapElements = new HeapElement<Score, X>* [_size+1]; // allocate
00128         for (int i = 0; i < s+1; ++i) {
00129             heapElements[i] = 0;
00130         }  
00131     }
00132     
00133 
00134     ~MinPriorityQueue() {
00135         for (int i = 0; i < s+1; ++i) {
00136             if (heapElements[i] != 0) {
00137                 delete heapElements[i];
00138                 heapElements[i] = 0;
00139             }
00140         }
00141         delete [] heapElements;
00142     }
00143     
00144     
00145     bool empty() const { return number == 0; }
00146     int count() const { return number; }
00147     int size() const { return s; }  
00148     
00149     //return the Object with the min. score
00150     const X & getMin() const {              
00151         return heapElements[1]->element();
00152     } 
00153     
00154 
00155     
00156     void decreasePriority(const HeapElement<Score, X> *elem, // handle to the element
00157                             Score sc // new score, muss be smaller then the old score
00158                             ) {
00159         int i = elem->pos;
00160         OGDF_ASSERT(i <= s);
00161         if (heapElements[i]->score_value() < sc)
00162             throw "New key is greater than current key.";
00163         heapElements[i]->v = sc; 
00164         while (i > 1 && (heapElements[getParent(i)]->score_value() > heapElements[i]->score_value()) ) {
00165             swap(i, getParent(i));
00166             i = getParent(i);
00167         }       
00168     }
00169 
00170 
00171     // return a handle to the new inserted element
00172     const HeapElement<Score, X> * insert(const HeapElement<Score, X> &elem) {       
00173         HeapElement<Score, X> *h_elem = new HeapElement<Score, X>(elem); // make a copy
00174         ++number;
00175         OGDF_ASSERT(number <= s);
00176         h_elem->pos = number; // store the position         
00177         heapElements[number] = h_elem;      
00178         int i = number;
00179         while ( (i > 1) && ( heapElements[getParent(i)]->score_value() > heapElements[i]->score_value()) ) {
00180             swap(i, getParent(i));
00181             i = getParent(i);
00182         }       
00183         return h_elem;
00184     }
00185     
00186 
00187     // return the smallest element and remove it from the queue
00188     HeapElement<Score, X> pop() {
00189         if (empty())
00190             throw "Heap underflow error!";      
00191         HeapElement<Score, X> obj = *heapElements[1];   
00192         HeapElement<Score, X> * p = heapElements[1];
00193         swap(1, number);        
00194         --number;
00195         delete p;
00196         minHeapify(1);
00197         OGDF_ASSERT(number+1 <= s);
00198         heapElements[number+1] = 0;
00199         return obj;
00200     }
00201         
00202     
00203     
00204     /*********************************************************************************/
00205     // debug
00206     void outHeap() {
00207         cout << "\nHeap Array: \n";
00208         for (int i = 0; i < s+1; i++) {
00209             HeapElement<Score, X> *obj = heapElements[i];
00210             if (obj != NULL)
00211                 cout << "score: " << obj->score_value() << "; elem: " << obj->element() << "; index "<< i << "; pos: " << obj->pos << endl << flush;
00212             else 
00213                 cout << "index: " << i << " value: null;" <<  endl << flush;    
00214         }       
00215     }
00216      
00217 };
00218 
00219 
00220 }// namespace
00221 
00222 #endif /*MINPRIORITYQUEUE_H_*/