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