00001
00002
00003
00004
00005
00006
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;
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);
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;
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> {
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) {
00250 PushResult ret = Accepted;
00251 if(capacity() == size()) {
00252 if(BinaryHeapSimple<X,INDEX>::top() >= x) {
00253 out = x;
00254 return Rejected;
00255 }
00256 out = BinaryHeapSimple<X,INDEX>::pop();
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)
00274 return;
00275 BinaryHeapSimple<X,INDEX>::pop();
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 {
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
00333
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 }
00348
00349
00350 #endif