Open
Graph Drawing
Framework

 v.2007.11
 

MinHeap.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 1.7 $
00003  * 
00004  * last checkin:
00005  *   $Author: klein $ 
00006  *   $Date: 2007-11-12 15:53:31 +0100 (Mo, 12 Nov 2007) $ 
00007  ***************************************************************/
00008  
00050 #ifdef _MSC_VER
00051 #pragma once
00052 #endif
00053 
00054 #ifndef OGDF_MIN_HEAP_H
00055 #define OGDF_MIN_HEAP_H
00056 
00057 #include<ogdf/basic/Array.h>
00058 
00059 namespace ogdf {
00060 
00062 
00066 template<class Score, class X> class Valued {
00067     Score v;
00068     X x;
00069 public:
00071     Valued() : v(0), x(0) {};
00073     Valued(Score vt, X xt) : v(vt), x(xt) {}
00075     Valued(const Valued& V) : v(V.v), x(V.x) {}
00077     Score value() const { return v; }
00079     X item() const { return x;}
00081     bool operator<(const Valued<Score,X>& V) const { return v<V.v; }
00083     bool operator<=(const Valued<Score,X>& V) const { return v<=V.v; }
00085     bool operator>(const Valued<Score,X>& V) const { return v>V.v; }
00087     bool operator>=(const Valued<Score,X>& V) const { return v>=V.v; }
00089     bool operator==(const Valued<Score,X>& V) const { return v==V.v; }
00091     bool operator!=(const Valued<Score,X>& V) const { return v!=V.v; }
00092 };
00093 
00094 
00096 
00109 template<class X, class INDEX = int>
00110 class MinHeap { 
00111 private:
00112     Array<X,INDEX> data; // array starts at index 1
00113     INDEX num;
00114 public:
00116     MinHeap(INDEX size) : data(1, size), num(0) {}
00117 
00119     bool empty() const { return num == 0; }
00121     INDEX size() const { return num; }
00122     
00124     void clear() { num = 0; }
00125 
00127     const X& top() const {
00128         return data[1];
00129     }
00130     
00132     void push(X& x) {
00133         X y;
00134         if(num == capacity())
00135             data.grow(capacity(),y); // double the size & init with nulls
00136         data[++num] = x;
00137         heapup(num);
00138     }
00139     
00141     X pop() {
00142         data.swap(1, num--);
00143         heapdown();
00144         return data[num+1];
00145     }
00146     
00148     const X& operator[](INDEX idx) const {
00149         return data[idx+1];
00150     }
00151     
00152 
00153 protected:
00155     INDEX capacity() const { return data.size(); }
00156 
00157     void heapup(INDEX idx) {
00158         INDEX papa;
00159         while( (papa = idx/2) > 0) {
00160             if( data[papa] > data[idx] ) {
00161                 data.swap(papa, idx);
00162                 idx = papa;
00163             } else return; //done
00164         }
00165     }
00166     
00167     void heapdown() {
00168         INDEX papa = 1;
00169         INDEX son;
00170         while(true) {
00171             if( (son = 2*papa) < num && data[son+1] < data[son] )
00172                 son++;
00173             if( son <= num && data[son] < data[papa]) {
00174                 data.swap(papa, son);
00175                 papa = son;
00176             } else return;
00177         }       
00178     }   
00179 };
00180 
00182 
00190 template<class X, class INDEX = int>
00191 class Top10Heap : protected MinHeap<X,INDEX> { // favors the 10 highest values...
00192 public:
00194     enum PushResult { Accepted, Rejected, Swapped };
00195     
00197     static bool successful(PushResult r) { return r != Rejected; }
00199     static bool returnedSomething(PushResult r) { return r != Accepted; }
00200 
00202     Top10Heap() : MinHeap<X,INDEX>(10) {}
00204     Top10Heap(INDEX size) : MinHeap<X,INDEX>(size) {}
00205 
00207     bool empty() const { return MinHeap<X,INDEX>::empty(); }
00209     bool full() const { return size() == capacity(); }
00211     INDEX size() const { return MinHeap<X,INDEX>::size(); }
00213     INDEX capacity() const { return MinHeap<X,INDEX>::capacity(); }
00214 
00216     void clear() { MinHeap<X,INDEX>::clear(); }
00217 
00219 
00235     PushResult push(X& x, X& out) { // returns element that got kicked out - out is uninitialized if heap wasn't full (i.e. PushResult equals Accepted)
00236         PushResult ret = Accepted;
00237         if(capacity() == size()) {
00238             if(MinHeap<X,INDEX>::top() >= x) {// reject new item since it's too bad
00239                 out = x;
00240                 return Rejected;
00241             }
00242             out = MinHeap<X,INDEX>::pop(); // remove worst first
00243             ret = Swapped;
00244         }
00245         MinHeap<X,INDEX>::push(x);
00246         return ret;
00247     }
00248     
00250 
00253     void pushBlind(X& x) {
00254         if(capacity() == size()) {
00255             if(MinHeap<X,INDEX>::top() >= x) // reject new item since it's too bad
00256                 return;
00257             MinHeap<X,INDEX>::pop(); // remove worst first
00258         }
00259         MinHeap<X,INDEX>::push(x);
00260     }
00261     
00263 
00267     const X& operator[](INDEX idx) const { // ATTN: simulate index starting at 0, to be "traditional" to the outside!!!
00268         return MinHeap<X,INDEX>::operator[](idx);
00269     }
00270 };
00271 
00272 } // end namespace ogdf
00273 
00274 
00275 #endif


© 1999-2007 by oreas GmbH, © 2005-2007 by University Dortmund and University Cologne.

Generated on Thu Nov 22 19:40:01 2007 by doxygen 1.5.4.