Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef DD_HEAP_H
00025 #define DD_HEAP_H
00026
00041 #include <assert.h>
00042 #include <vector>
00043
00044
00045 template <class T>
00046 class DHeap: public std::vector<T> {
00047 public:
00048
00049 void push(const T& elt) {
00050 this->push_back(elt);
00051 bubbleUp(this->size()-1);
00052 }
00053
00054 T &min() { return this->front(); }
00055
00056 T popMin() {
00057 T elt = this->front();
00058
00059 this->front() = this->back();
00060 this->pop_back();
00061
00062 trickleDownMin(0);
00063 return elt;
00064 }
00065
00066
00067 T &max() {
00068 if(this->size() == 1) return at(0);
00069 return at(1);
00070 }
00071
00072 T popMax() {
00073 int p = 1;
00074 if(this->size() == 1) p = 0;
00075 T elt = at(p);
00076
00077 at(p) = this->back();
00078 this->pop_back();
00079 trickleDownMax(p);
00080 return elt;
00081 }
00082
00083
00084 void rebuild() {
00085 for(unsigned int i = 0; i < this->size(); i++)
00086 bubbleUp(i);
00087 }
00088
00089 protected:
00090 T &at(int n) { return std::vector<T>::at(n); }
00091
00092 int isMax(int e) const { return e & 1; }
00093 int parentMin(int i) const { return (((i+2)>>2)<<1) - 2; }
00094 int parentMax(int i) const { return (((i+2)>>2)<<1) - 1; }
00095 int leftChildMin(int i) const { return (((i+2)>>1)<<2) -2; }
00096 int leftChildMax(int i) const { return (((i+2)>>1)<<2) -1; }
00097
00098 void swap(int a, int b) { T tmp = at(a); at(a) = at(b); at(b) = tmp; }
00099
00100
00101 int smallestChild(int i) {
00102 int l = leftChildMin(i);
00103 if(l >= this->size()) return i;
00104
00105 int r = l+2;
00106 if(r < this->size() && at(r) < at(l))
00107 return r;
00108 return l;
00109 }
00110
00111 int greatestChild(int i) {
00112 int l = leftChildMax(i);
00113 if(l >= this->size()) return i;
00114
00115 int r = l+2;
00116 if(r < this->size() && at(r) > at(l))
00117 return r;
00118 return l;
00119 }
00120
00121
00122
00123 void trickleDownMin(int i) {
00124 while(1) {
00125
00126
00127 unsigned int m = leftChildMin(i);
00128 if(m >= this->size()) break;
00129 unsigned int r = m+2;
00130 if(r < this->size() && at(r) < at(m))
00131 m = r;
00132
00133 if(at(m) < at(i)) {
00134 swap(i, m);
00135 i = m;
00136 } else
00137 break;
00138
00139 m = i+1;
00140 if(m >= this->size()) break;
00141 if(at(m) < at(i))
00142 swap(i, m);
00143 }
00144 }
00145
00146 void trickleDownMax(int i) {
00147 while(1) {
00148
00149
00150 unsigned int m = leftChildMax(i);
00151 if(m >= this->size()) break;
00152 unsigned int r = m+2;
00153 if(r < this->size() && at(r) > at(m))
00154 m = r;
00155
00156 if(at(m) > at(i)) {
00157 swap(i, m);
00158 i = m;
00159 } else
00160 break;
00161
00162 m = i-1;
00163 if(m >= this->size()) break;
00164 if(at(m) > at(i)) {
00165 swap(i, m);
00166 }
00167 }
00168 }
00169
00170 void bubbleUpMin(int i) {
00171 while(1) {
00172 int m = parentMin(i);
00173 if(m < 0) break;
00174 if(at(m) > at(i)) {
00175 swap(i, m);
00176 i = m;
00177 } else
00178 break;
00179 }
00180 }
00181
00182 void bubbleUpMax(int i) {
00183 while(1) {
00184 int m = parentMax(i);
00185 if(m < 0) break;
00186 if(at(m) < at(i)) {
00187 swap(i, m);
00188 i = m;
00189 } else
00190 break;
00191 }
00192 }
00193
00194 void bubbleUp(int i) {
00195 if(isMax(i)) {
00196 int m = i-1;
00197 if(at(m) > at(i)) {
00198 swap(i, m);
00199 bubbleUpMin(m);
00200 } else
00201 bubbleUpMax(i);
00202 } else {
00203 int m = parentMax(i);
00204 if(m < 0) return;
00205 if(at(m) < at(i)) {
00206 swap(i, m);
00207 bubbleUpMax(m);
00208 } else
00209 bubbleUpMin(i);
00210 }
00211 }
00212
00213 public:
00215 bool isHeap() {
00216 int s = this->size();
00217 for(int i = 0; i < s; i += 2) {
00218 if(i+1 < s && at(i) > at(i+1)) return false;
00219 int l = leftChildMin(i);
00220 if(l < s && at(i) > at(l)) return false;
00221 int r = l + 2;
00222 if(r < s && at(i) > at(r)) return false;
00223 }
00224 for(int i = 1; i < s; i += 2) {
00225 int l = leftChildMax(i);
00226 if(l < s && at(i) < at(l)) return false;
00227 int r = l + 2;
00228 if(r < s && at(i) < at(r)) return false;
00229 }
00230 return true;
00231 }
00232 };
00233
00236 template <class T>
00237 class PtrDHeap {
00238 private:
00239 class Item {
00240 public:
00241 T *value;
00242 Item(T *val): value(val) {}
00243 bool operator<(const Item &i) const { return *value < *i.value; }
00244 bool operator>(const Item &i) const { return *value > *i.value; }
00245 };
00246 DHeap<Item> heap;
00247
00248 public:
00249 T *push(T *t) {
00250 Item i(t);
00251 heap.push(i);
00252 return i.value;
00253 }
00254 void push_back(T *t) {
00255 heap.push_back(Item(t));
00256 }
00257 int size() { return heap.size(); }
00258 void resize(int n) { assert(n <= (int)heap.size()); return heap.resize(n, Item(NULL)); }
00259 void clear() { heap.clear(); }
00260 T &min() { Item &i = heap.min(); return *i.value; }
00261 T *popMin() { Item i = heap.popMin(); return i.value; }
00262
00263 T &max() { Item &i = heap.max(); return *i.value; }
00264 T *popMax() { Item i = heap.popMax(); return i.value; }
00265
00266 void rebuild() { heap.rebuild(); }
00267 T &operator[](int i) {
00268 return *(heap[i].value);
00269 }
00270 Item &at(int i) { return heap[i]; }
00271 bool isHeap() { return heap.isHeap(); }
00272 };
00273
00274 #endif