00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef W_HEAP_H
00031 #define W_HEAP_H
00032
00033 #include "w_defines.h"
00034
00035
00036
00037 #include "w_base.h"
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 template <class T, class Cmp>
00079 class Heap
00080 {
00081 public:
00082 Heap(const Cmp& cmpFunction,
00083 int initialNumElements = 32);
00084 ~Heap();
00085
00086
00087 int NumElements() const;
00088
00089
00090 T RemoveFirst();
00091
00092
00093 T RemoveN(int i);
00094
00095
00096 void AddElement(const T& elem);
00097
00098
00099 void AddElementDontHeapify(const T& elem);
00100
00101 void Heapify();
00102
00103
00104 T& First();
00105
00106
00107 T& Value(int i);
00108
00109
00110 const T& Second() const;
00111
00112
00113
00114 void ReplacedFirst();
00115
00116
00117
00118
00119 void IncreasedN(int i);
00120
00121
00122
00123
00124 void DecreasedN(int i);
00125
00126
00127 void CheckHeap() const;
00128
00129
00130 void Print(ostream& out) const;
00131
00132
00133
00134 bool HeapProperty(int root) const;
00135
00136 protected:
00137 int numElements;
00138 int maxNumElements;
00139 T* elements;
00140 const Cmp& cmp;
00141
00142 int LeftChild(int i) const;
00143 int RightChild(int i) const;
00144 int RightSibling(int i) const;
00145 int Parent(int i) const;
00146
00147 void PrintRoot(ostream& out, int rootElem, int indentLevel) const;
00148 void CheckHeapRoot(int rootElem) const;
00149
00150 bool HeapProperty(int lower, int upper) const;
00151
00152
00153 void SiftDown(int rootElem);
00154
00155 void SiftUp(int rootElem);
00156
00157
00158 void GrowElements(int newSize);
00159 };
00160
00161
00162
00163
00164 template<class T, class Cmp>
00165 inline int Heap<T, Cmp>::LeftChild(int i) const
00166 {
00167 return 2 * i + 1;
00168 }
00169
00170
00171 template<class T, class Cmp>
00172 inline int Heap<T, Cmp>::RightChild(int i) const
00173 {
00174 return 2 * i + 2;
00175 }
00176
00177
00178 template<class T, class Cmp>
00179 inline int Heap<T, Cmp>::RightSibling(int i) const
00180 {
00181 return i + 1;
00182 }
00183
00184
00185 template<class T, class Cmp>
00186 inline int Heap<T, Cmp>::Parent(int i) const
00187 {
00188 return (i - 1) / 2;
00189 }
00190
00191
00192
00193
00194 template<class T, class Cmp>
00195 inline void Heap<T, Cmp>::CheckHeap() const
00196 {
00197 w_assert9(HeapProperty(0));
00198 }
00199
00200
00201 template<class T, class Cmp>
00202 inline int Heap<T, Cmp>::NumElements() const
00203 {
00204 return numElements;
00205 }
00206
00207
00208 template<class T, class Cmp>
00209 inline void Heap<T, Cmp>::Print(ostream& out) const
00210 {
00211 PrintRoot(out, 0, 0);
00212 }
00213
00214
00215 template<class T, class Cmp>
00216 inline void Heap<T, Cmp>::ReplacedFirst()
00217 {
00218 SiftDown(0);
00219 }
00220
00221 template<class T, class Cmp>
00222 inline void Heap<T, Cmp>::IncreasedN(int n)
00223 {
00224 SiftUp(n);
00225 }
00226
00227 template<class T, class Cmp>
00228 inline void Heap<T, Cmp>::DecreasedN(int n)
00229 {
00230 SiftDown(n);
00231 }
00232
00233
00234 template<class T, class Cmp>
00235 Heap<T, Cmp>::Heap(const Cmp& cmpFunction, int initialNumElements)
00236 :
00237 numElements(0),
00238 maxNumElements(initialNumElements),
00239 elements(0),
00240 cmp(cmpFunction)
00241 {
00242 elements = new T[initialNumElements];
00243 }
00244
00245
00246 template<class T, class Cmp>
00247 Heap<T, Cmp>::~Heap()
00248 {
00249 delete[] elements;
00250 }
00251
00252
00253
00254
00255 template<class T, class Cmp>
00256 T Heap<T, Cmp>::RemoveN(int i)
00257 {
00258 w_assert9(numElements > 0);
00259 T temp = elements[i];
00260 bool smaller = cmp.gt(elements[i], elements[--numElements]);
00261 elements[i] = elements[numElements];
00262 if(smaller) {
00263 SiftDown(i);
00264 } else {
00265 SiftUp(i);
00266 }
00267 return temp;
00268 }
00269
00270 template<class T, class Cmp>
00271 T Heap<T, Cmp>::RemoveFirst()
00272 {
00273
00274
00275
00276
00277
00278 T temp = elements[0];
00279 elements[0] = elements[--numElements];
00280 SiftDown(0);
00281 return temp;
00282 }
00283
00284
00285
00286
00287
00288 template<class T, class Cmp>
00289 T& Heap<T, Cmp>::First()
00290 {
00291 w_assert9(numElements > 0);
00292 return elements[0];
00293 }
00294
00295 template<class T, class Cmp>
00296 T& Heap<T, Cmp>::Value(int i)
00297 {
00298 w_assert9(i < numElements && i >= 0);
00299 return elements[i];
00300 }
00301
00302
00303
00304
00305 template<class T, class Cmp>
00306 const T& Heap<T, Cmp>::Second() const
00307 {
00308 w_assert9(numElements > 1);
00309 int second = LeftChild(0);
00310 if (RightSibling(second) < numElements) {
00311 if (cmp.gt(elements[RightSibling(second)], elements[second])) {
00312 second = RightSibling(second);
00313 }
00314 }
00315 return elements[second];
00316 }
00317
00318
00319
00320
00321
00322 template<class T, class Cmp>
00323 void Heap<T, Cmp>::AddElement(const T& elem)
00324 {
00325 if (numElements >= maxNumElements) {
00326 GrowElements(2 * maxNumElements);
00327 }
00328
00329 int rootElem = numElements++;
00330 while (rootElem > 0) {
00331 if (cmp.gt(elem, elements[Parent(rootElem)])) {
00332 elements[rootElem] = elements[Parent(rootElem)];
00333 rootElem = Parent(rootElem);
00334 } else {
00335 break;
00336 }
00337 }
00338 elements[rootElem] = elem;
00339 }
00340
00341
00342
00343
00344
00345 template<class T, class Cmp>
00346 void Heap<T, Cmp>::AddElementDontHeapify(const T& elem)
00347 {
00348 if (numElements >= maxNumElements) {
00349 GrowElements(2 * maxNumElements);
00350 }
00351 elements[numElements++] = elem;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 template<class T, class Cmp>
00367 void Heap<T, Cmp>::SiftDown(int rootElem)
00368 {
00369
00370
00371
00372 if(LeftChild(rootElem) < numElements) {
00373 w_assert9(HeapProperty(LeftChild(rootElem)));
00374 }
00375
00376 if (numElements > 1) {
00377 const T rootValue = elements[rootElem];
00378 while (rootElem <= Parent(numElements - 1)) {
00379 w_assert9(LeftChild(rootElem) < numElements);
00380
00381
00382
00383 int child = LeftChild(rootElem);
00384 if (RightSibling(child) < numElements) {
00385 if (cmp.gt(elements[RightSibling(child)], elements[child])) {
00386 child = RightSibling(child);
00387 }
00388 }
00389
00390
00391
00392 if (cmp.gt(elements[child], rootValue)) {
00393 elements[rootElem] = elements[child];
00394 rootElem = child;
00395 } else {
00396 break;
00397 }
00398 }
00399 elements[rootElem] = rootValue;
00400 }
00401
00402
00403
00404
00405
00406
00407
00408 w_assert9(HeapProperty(rootElem));
00409 }
00410
00411 template<class T, class Cmp>
00412 void Heap<T, Cmp>::SiftUp(int rootElem)
00413 {
00414
00415
00416
00417 if(rootElem > 0) {
00418 w_assert9(HeapProperty(0, Parent(rootElem)));
00419 }
00420
00421 if(rootElem > 0) {
00422 const T rootValue = elements[rootElem];
00423 int i = rootElem;
00424 while (i > 0) {
00425 if (cmp.gt(rootValue, elements[Parent(i)])) {
00426
00427 elements[i] = elements[Parent(i)];
00428 i = Parent(i);
00429 } else {
00430 break;
00431 }
00432 }
00433 elements[i] = rootValue;
00434 }
00435
00436
00437
00438 w_assert9(HeapProperty(0, rootElem));
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 template<class T, class Cmp>
00451 void Heap<T, Cmp>::Heapify()
00452 {
00453 if (NumElements() > 0) {
00454 for (int i = Parent(NumElements() - 1); i >= 0; --i) {
00455 SiftDown(i);
00456 }
00457 #if W_DEBUG_LEVEL > 2
00458 CheckHeap();
00459 #endif
00460 }
00461 }
00462
00463
00464
00465
00466 template<class T, class Cmp>
00467 void Heap<T, Cmp>::GrowElements(int newSize)
00468 {
00469 w_assert9(newSize >= numElements);
00470
00471 T* newElements = new T[newSize];
00472 for (int i = 0; i < numElements; ++i) {
00473 newElements[i] = elements[i];
00474 }
00475 delete[] elements;
00476 elements = newElements;
00477 maxNumElements = newSize;
00478 }
00479
00480
00481
00482
00483 template<class T, class Cmp>
00484 void Heap<T, Cmp>::CheckHeapRoot(int rootElem) const
00485 {
00486 if (rootElem < numElements) {
00487 if (LeftChild(rootElem) < numElements) {
00488 w_assert1(!cmp.gt(elements[LeftChild(rootElem)],
00489 elements[rootElem]));
00490 CheckHeapRoot(LeftChild(rootElem));
00491 }
00492 if (RightChild(rootElem) < numElements) {
00493 w_assert1(!cmp.gt(elements[RightChild(rootElem)],
00494 elements[rootElem]));
00495 CheckHeapRoot(RightChild(rootElem));
00496 }
00497 }
00498 }
00499
00500 template<class T, class Cmp>
00501 bool Heap<T, Cmp>::HeapProperty(int root) const
00502 {
00503 return HeapProperty(root, numElements);
00504 }
00505
00506
00507
00508
00509 template<class T, class Cmp>
00510 bool Heap<T, Cmp>::HeapProperty(int top, int bottom) const
00511 {
00512 int last = (bottom > numElements) ? numElements : bottom;
00513
00514 for(int i= LeftChild(top); i<last; i++) {
00515 if( cmp.gt( elements[i] , elements[Parent(i)] ) ) return false;
00516 }
00517 return true;
00518 }
00519
00520
00521
00522
00523 template<class T, class Cmp>
00524 void Heap<T, Cmp>::PrintRoot(ostream& out, int rootElem, int indentLevel) const
00525 {
00526 if (rootElem < NumElements()) {
00527 PrintRoot(out, LeftChild(rootElem), indentLevel + 1);
00528 for (int i = 0; i < indentLevel; i++) {
00529 cout << '\t';
00530 }
00531 cout << elements[rootElem] << '\n';
00532 PrintRoot(out, RightChild(rootElem), indentLevel + 1);
00533 }
00534 }
00535
00536
00537
00538 #endif