Open
Graph Drawing
Framework

 v.2010.10
 

MinHeap.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 2027 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2010-09-01 11:55:17 +0200 (Wed, 01 Sep 2010) $ 
00007  ***************************************************************/
00008  
00052 #ifdef _MSC_VER
00053 #pragma once
00054 #endif
00055 
00056 #ifndef OGDF_MIN_HEAP_H
00057 #define OGDF_MIN_HEAP_H
00058 
00059 #include<ogdf/basic/Array.h>
00060 
00061 namespace ogdf {
00062 
00064 
00068 template<class X, class Priority=double> class Prioritized {
00069     X x;
00070     Priority p;
00071 public:
00073     Prioritized() : x(0), p(0) {};
00075     Prioritized(X xt, Priority pt) : x(xt),p(pt) {}
00077     Prioritized(const Prioritized& P) : x(P.x),p(P.p) {}
00079     Priority priority() const { return p; }
00081     X item() const { return x;}
00083     bool operator<(const Prioritized<X,Priority>& P) const { return p<P.p; }
00085     bool operator<=(const Prioritized<X,Priority>& P) const { return p<=P.p; }
00087     bool operator>(const Prioritized<X,Priority>& P) const { return p>P.p; }
00089     bool operator>=(const Prioritized<X,Priority>& P) const { return p>=P.p; }
00091     bool operator==(const Prioritized<X,Priority>& P) const { return p==P.p; }
00093     bool operator!=(const Prioritized<X,Priority>& P) const { return p!=P.p; }
00094 };
00095 
00096 
00098 
00111 template<class X, class INDEX = int>
00112 class BinaryHeapSimple {    
00113 private:
00114     Array<X,INDEX> data; // array starts at index 1
00115     INDEX num;
00116 public:
00118     BinaryHeapSimple(INDEX size) : data(1, size), num(0) {}
00119 
00121     bool empty() const { return num == 0; }
00123     INDEX size() const { return num; }
00124     
00126     void clear() { num = 0; }
00127 
00129     const X& top() const {
00130         return data[1];
00131     }
00133     inline const X& getMin() const {
00134         return top();
00135     }
00136     
00138     void push(X& x) {
00139         X y;
00140         if(num == capacity())
00141             data.grow(capacity(),y); // double the size & init with nulls
00142         data[++num] = x;
00143         heapup(num);
00144     }
00146     inline void insert(X& x) {
00147         push(x);
00148     }
00149     
00151     X pop() {
00152         data.swap(1, num--);
00153         heapdown();
00154         return data[num+1];
00155     }
00157     inline X extractMin() {
00158         return pop();
00159     }
00160     
00162     const X& operator[](INDEX idx) const {
00163         return data[idx+1];
00164     }
00165     
00166 
00167 protected:
00169     INDEX capacity() const { return data.size(); }
00170 
00171     void heapup(INDEX idx) {
00172         INDEX papa;
00173         while( (papa = idx/2) > 0) {
00174             if( data[papa] > data[idx] ) {
00175                 data.swap(papa, idx);
00176                 idx = papa;
00177             } else return; //done
00178         }
00179     }
00180     
00181     void heapdown() {
00182         INDEX papa = 1;
00183         INDEX son;
00184         while(true) {
00185             if( (son = 2*papa) < num && data[son+1] < data[son] )
00186                 son++;
00187             if( son <= num && data[son] < data[papa]) {
00188                 data.swap(papa, son);
00189                 papa = son;
00190             } else return;
00191         }       
00192     }   
00193 };
00194 
00196 
00204 template<class X, class INDEX = int>
00205 class Top10Heap : protected BinaryHeapSimple<X,INDEX> { // favors the 10 highest values...
00206 public:
00208     enum PushResult { Accepted, Rejected, Swapped };
00209     
00211     static bool successful(PushResult r) { return r != Rejected; }
00213     static bool returnedSomething(PushResult r) { return r != Accepted; }
00214 
00216     Top10Heap() : BinaryHeapSimple<X,INDEX>(10) {}
00218     Top10Heap(INDEX size) : BinaryHeapSimple<X,INDEX>(size) {}
00219 
00221     bool empty() const { return BinaryHeapSimple<X,INDEX>::empty(); }
00223     bool full() const { return size() == capacity(); }
00225     INDEX size() const { return BinaryHeapSimple<X,INDEX>::size(); }
00227     INDEX capacity() const { return BinaryHeapSimple<X,INDEX>::capacity(); }
00228 
00230     void clear() { BinaryHeapSimple<X,INDEX>::clear(); }
00231 
00233 
00249     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)
00250         PushResult ret = Accepted;
00251         if(capacity() == size()) {
00252             if(BinaryHeapSimple<X,INDEX>::top() >= x) {// reject new item since it's too bad
00253                 out = x;
00254                 return Rejected;
00255             }
00256             out = BinaryHeapSimple<X,INDEX>::pop(); // remove worst first
00257             ret = Swapped;
00258         }
00259         BinaryHeapSimple<X,INDEX>::push(x);
00260         return ret;
00261     }
00263     inline PushResult insert(X& x, X& out) {
00264         return push(x, out);
00265     }
00266     
00268 
00271     void pushBlind(X& x) {
00272         if(capacity() == size()) {
00273             if(BinaryHeapSimple<X,INDEX>::top() >= x) // reject new item since it's too bad
00274                 return;
00275             BinaryHeapSimple<X,INDEX>::pop(); // remove worst first
00276         }
00277         BinaryHeapSimple<X,INDEX>::push(x);
00278     }
00280     inline void insertBlind(X& x, X& out) {
00281         return pushBlind(x, out);
00282     }
00283     
00285 
00289     const X& operator[](INDEX idx) const { // ATTN: simulate index starting at 0, to be "traditional" to the outside!!!
00290         return BinaryHeapSimple<X,INDEX>::operator[](idx);
00291     }
00292 };
00293 
00295 
00303 template<class X, class Priority=double, class STATICCOMPARER=StdComparer<X>, class INDEX = int >
00304 class DeletingTop10Heap : public Top10Heap<Prioritized<X*,Priority>,INDEX > {
00305 public:
00307     DeletingTop10Heap(int size) : Top10Heap<Prioritized<X*, Priority>,INDEX >(size) {}
00309 
00314     void pushAndDelete(X* x, Priority p) {
00315         Prioritized<X*, Priority> vo;
00316         Prioritized<X*, Priority> nv(x, p);
00317         if(returnedSomething( Top10Heap<Prioritized<X*, Priority>,INDEX >::push(nv, vo) ))
00318             delete vo.item();
00319     }
00321     inline void insertAndDelete(X* x, Priority p) {
00322         pushAndDelete(x, p);
00323     }
00325 
00329     void pushAndDeleteNoRedundancy(X* x, Priority p) {
00330         for(INDEX i = Top10Heap<Prioritized<X*,Priority>,INDEX >::size(); i-->0;) {
00331             X* k = Top10Heap<Prioritized<X*,Priority>,INDEX >::operator[](i).item();
00332 //          OGDF_ASSERT( x )
00333 //          OGDF_ASSERT( k )
00334             if(STATICCOMPARER::equal(k,x)) {
00335                 delete x;
00336                 return;
00337             }
00338         }
00339         pushAndDelete(x, p);
00340     }       
00342     inline void insertAndDeleteNoRedundancy(X* x, Priority p) {
00343         pushAndDeleteNoRedundancy(p, x);
00344     }
00345 };
00346 
00347 } // end namespace ogdf
00348 
00349 
00350 #endif