Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00041 #ifdef _MSC_VER
00042 #pragma once
00043 #endif
00044
00045 #ifndef OGDF_BINARY_HEAP_H
00046 #define OGDF_BINARY_HEAP_H
00047
00048 #include<ogdf/basic/Array.h>
00049
00050 namespace ogdf {
00051
00052
00053
00054
00055 template <class X, class Priority=double, class INDEX=int>
00056 class OGDF_EXPORT BinaryHeap {
00057
00058 public:
00059
00060 class Element {
00061
00062 friend class BinaryHeap<X, Priority, INDEX>;
00063
00064 private:
00065 Priority priority;
00066 X elem;
00067 INDEX backIdx ;
00068
00069
00070 Element() { }
00071
00072
00073 Element(X x, Priority prior) : priority(prior), elem(x) { }
00074
00075
00076 Element(const Element &origElem): priority(origElem.priority), elem(origElem.elem), backIdx(origElem.backIdx) { }
00077
00078 public:
00079
00080
00081 Priority getPriority() const { return priority; }
00082
00083
00084 const X &getElement() const { return elem; }
00085
00086
00087 INDEX getPos() const { return backIdx; }
00088 };
00089
00090
00092 BinaryHeap(INDEX c) : data(1, c, 0), s(0) { }
00093
00095 ~BinaryHeap() {
00096 for (INDEX i = 1; i <= s; ++i) {
00097 delete data[i];
00098 data[i] = 0;
00099 }
00100 }
00101
00103 bool empty() const { return s == 0; }
00104
00106 INDEX size() const { return s; }
00107
00108
00109
00111 void decPriority(const Element &elem,
00112 Priority prior
00113 ) {
00114 INDEX i = elem.backIdx;
00115
00116 OGDF_ASSERT(i <= s);
00117
00118 if (data[i]->getPriority() < prior)
00119 throw "New key is greater than current key.";
00120
00121 data[i]->priority = prior;
00122 while (i > 1 && (data[getParent(i)]->getPriority() > data[i]->getPriority()) ) {
00123 swap(i, getParent(i));
00124 i = getParent(i);
00125 }
00126 }
00127
00129 const Element & insert(X obj, Priority prior) {
00130 Element *h_elem = new Element (obj, prior);
00131 ++s;
00132 if (s == capacity())
00133 data.grow(capacity(), 0);
00134 h_elem->backIdx = s;
00135 data[s] = h_elem;
00136 INDEX i = s;
00137 while ( (i > 1) && ( data[getParent(i)]->getPriority() > data[i]->getPriority()) ) {
00138 swap(i, getParent(i));
00139 i = getParent(i);
00140 }
00141 return *h_elem;
00142 }
00143
00145 const Element & push(X obj, Priority prior) {
00146 return insert(obj, prior);
00147 }
00148
00150 const X & getMin() const {
00151 return data[1]->getElement();
00152 }
00153
00155 const X & top() const {
00156 return getMin();
00157 }
00158
00160 X extractMin() {
00161 if (empty())
00162 throw "Heap underflow error!";
00163
00164 Element copy = *data[1];
00165 Element *p = data[1];
00166 swap(1, s);
00167 --s;
00168 delete p;
00169 minHeapify(1);
00170 data[s+1] = 0;
00171 return copy.getElement();
00172 }
00173
00175 X pop() {
00176 return extractMin();
00177 }
00178
00180 void clear() {
00181 for (INDEX i = 1; i <= s; ++i) {
00182 delete data[i];
00183 data[i] = 0;
00184 }
00185 s = 0;
00186 }
00187
00189 const X & operator[](INDEX idx) const {
00190 return data[idx+1]->getElement();
00191 }
00192
00193
00194 private :
00195
00196 Array<Element *, INDEX> data;
00197 INDEX s;
00198
00200 INDEX capacity() const { return data.size(); }
00201
00202 void swap(INDEX pos1, INDEX pos2) {
00203 Element *tmp = data[pos1];
00204 data[pos1] = data[pos2];
00205 data[pos2] = tmp;
00206
00207 data[pos2]->backIdx = pos2;
00208 data[pos1]->backIdx = pos1;
00209 }
00210
00211
00212
00213 void minHeapify(INDEX pos) {
00214 INDEX l = getLeft(pos);
00215 INDEX r = getRight(pos);
00216 INDEX smallest;
00217 if (l <= size() && data[l]->getPriority() < data[pos]->getPriority() )
00218 smallest = l;
00219 else
00220 smallest = pos;
00221 if (r <= size() && data[r]->getPriority() < data[smallest]->getPriority())
00222 smallest = r;
00223 if (smallest != pos) {
00224 swap(pos, smallest);
00225 minHeapify(smallest);
00226 }
00227 }
00228
00229
00230 INDEX getParent(INDEX pos) const {return pos/2;}
00231
00232 INDEX getLeft(INDEX pos) const {return pos*2;}
00233
00234 INDEX getRight(INDEX pos) const {return pos*2+1;}
00235
00236 };
00237
00238 }
00239
00240 #endif