bheap.inc

Go to the documentation of this file.
00001 
00029 #ifndef ABA_BHEAP_INC
00030 #define ABA_BHEAP_INC
00031 
00032   template<class Type, class Key>
00033   ABA_BHEAP<Type, Key>::ABA_BHEAP(ABA_GLOBAL *glob, int size)
00034   :  
00035     glob_(glob),  
00036     heap_(glob, size),  
00037     keys_(glob, size),  
00038     n_(0)
00039     { }
00040 
00041   template<class Type, class Key>
00042   ABA_BHEAP<Type, Key>::ABA_BHEAP(ABA_GLOBAL *glob, 
00043                                   const ABA_BUFFER<Type> &elems, 
00044                                   const ABA_BUFFER<Key> &keys)
00045   :  
00046     glob_(glob),  
00047     heap_(glob, elems),  
00048     keys_(glob, keys),  
00049     n_(keys.number())
00050     {
00051       for (int i = father(n_-1); i>=0; --i)
00052         heapify(i);
00053     }
00054 
00055   template<class Type, class Key>
00056   ostream& operator<<(ostream& out, const ABA_BHEAP<Type, Key>& rhs)
00057   {
00058     for(int i = 0; i < rhs.n_; i ++)
00059       out << rhs.heap_[i] << " (" << rhs.keys_[i] << ")  ";
00060     out << endl;
00061     return out;
00062   }
00063 
00064   template<class Type, class Key>
00065   void ABA_BHEAP<Type, Key>::insert(Type elem, Key key)
00066   {
00068 #ifdef ABACUSSAFE
00069     if(n_ >= size()) {
00070       glob_->err() << "ABA_BHEAP::insert : bounded heap for " << size();
00071       glob_->err() << " elements is full" << endl;
00072       exit (Fatal);
00073     }
00074 #endif
00075 
00076     // go up towards the root and insert \a elem
00077     /* The position \a n_ of the array representing the heap becomes the
00078      * new leaf of corresponding binary tree. However, inserting the new
00079      * element at this position could destroy the heap property.
00080      * Therefore, we go up to the root until we find the position
00081      * for inserting the new element. While going up to this position
00082      * we move earlier inserted elements already to their new position.
00083      */
00084     int i = n_;
00085     int f = father(i);
00086 
00087     while (i > 0 && keys_[f] > key) {
00088       heap_[i] = heap_[f];
00089       keys_[i] = keys_[f];
00090       i        = f;
00091       f        = father(i);
00092     }
00093     heap_[i] = elem;
00094     keys_[i] = key;
00095     ++n_;
00096   
00097 
00098   }
00099 
00100   template<class Type, class Key>
00101   Type ABA_BHEAP<Type, Key>::getMin() const
00102   {
00103     // is the heap empty?
00104     /* The check on an empty heap is only performed if is the code
00105      * is compiled with the precompiler instruction {\tt -DABACUSSAFE}.
00106      */
00107 #ifdef ABACUSSAFE
00108     if (empty()) {
00109       glob_->err() << "ABA_BHEAP:: getMin/extractMin/getMinKey: heap is empty" << endl;
00110       exit (Fatal);
00111     }
00112 #endif
00113 
00114     return heap_[0];
00115   }
00116 
00117   template<class Type, class Key>
00118   Key ABA_BHEAP<Type, Key>::getMinKey() const
00119   {
00120     // is the heap empty?
00121     /* The check on an empty heap is only performed if is the code
00122      * is compiled with the precompiler instruction {\tt -DABACUSSAFE}.
00123      */
00124 #ifdef ABACUSSAFE
00125     if (empty()) {
00126       glob_->err() << "ABA_BHEAP:: getMin/extractMin/getMinKey: heap is empty" << endl;
00127       exit (Fatal);
00128     }
00129 #endif
00130     return keys_[0];
00131   }
00132 
00133   template<class Type, class Key>
00134   Type ABA_BHEAP<Type, Key>::extractMin()
00135   {
00136     Type min = getMin();
00137 
00138     --n_;
00139 
00140     if (n_ != 0) {
00141       heap_[0] = heap_[n_];
00142       keys_[0] = keys_[n_];
00143       heapify(0);
00144     }
00145 
00146     return min;
00147   }
00148 
00149   template<class Type, class Key>
00150   void ABA_BHEAP<Type, Key>::clear()
00151   {
00152     n_ = 0;
00153   }
00154 
00155   template<class Type, class Key>
00156   inline int ABA_BHEAP<Type, Key>::size() const
00157   {
00158     return heap_.size();
00159   }
00160 
00161   template <class Type, class Key>
00162   inline int ABA_BHEAP<Type, Key>::number() const
00163   {
00164     return n_;
00165   }
00166 
00167   template<class Type, class Key>
00168   inline bool ABA_BHEAP<Type, Key>::empty() const
00169   {
00170     if(n_ == 0) return true;
00171     return false;
00172   }
00173 
00174   template<class Type, class Key>
00175   void ABA_BHEAP<Type, Key>::realloc(int newSize)
00176   {
00177     heap_.realloc(newSize);
00178     keys_.realloc(newSize);
00179   }
00180   
00181   template<class Type, class Key>
00182   void ABA_BHEAP<Type, Key>::check() const
00183   {
00184     for(int i = 0; i < n_/2; i++) 
00185       if (keys_[i] > keys_[leftSon(i)] ||
00186             rightSon(i) < n_ && heap_[i] > heap_[rightSon(i)]) {
00187           glob_->err() << i << " violates heap" << endl;
00188           exit(Fatal);
00189       }
00190   }
00191 
00192   template <class Type, class Key>
00193   inline int ABA_BHEAP<Type, Key>::leftSon(int i) const
00194   {
00195     return 2*i + 1;
00196   }
00197 
00198   template <class Type, class Key>
00199   int ABA_BHEAP<Type, Key>::rightSon(int i) const
00200   {
00201     return 2*i + 2;
00202   }
00203 
00204   template <class Type, class Key>
00205   inline int ABA_BHEAP<Type, Key>::father(int i) const
00206   {
00207     return (i-1)/2;
00208   }
00209   
00210   template <class Type, class Key>
00211   void ABA_BHEAP<Type, Key>::heapify(int i)
00212   {
00214     int  l;        // left son of i
00215     int  r;        // right son of i
00216     int  smallest; // smallest heap element of i,l, and r
00217     Type tmp;      // temporary object for swapping elements of the heap
00218     Key  ktmp;     // temporary object for swapping the keys
00219 
00220     // restore the heap property
00221     /* Node \a i violates the heap property if it has a son with
00222      * a smaller key. If we swap the element and the key of node \a i
00223      * with the element and the key of the smaller one of its two sons,
00224      * then the heap property is restored for node \a i. However, it
00225      * might be now destroyed for node \a smallest. So we
00226      * iterate this process until no swap is performed.
00227      */
00228     while (i < n_) {
00230       l = leftSon(i);
00231       r = rightSon(i);
00232       if (l < n_ && keys_[i] > keys_[l])        smallest = l;
00233       else                                      smallest = i;
00234       if (r < n_ && keys_[smallest] > keys_[r]) smallest = r;
00235 
00236       if (smallest != i) {
00238         tmp            = heap_[i];
00239         heap_[i]        = heap_[smallest];
00240         heap_[smallest] = tmp;
00241 
00242         ktmp           = keys_[i];
00243         keys_[i]        = keys_[smallest];
00244         keys_[smallest] = ktmp;
00245 
00246         i = smallest;
00247       }
00248       else break;
00249     }
00250 
00251   }
00252 
00253 #endif   // ABA_BHEAP_INC

Generated on Tue Aug 14 18:09:53 2007 for ABACUS by  doxygen 1.5.1