Changes in lemon/bin_heap.h [463:88ed40ad0d4f:758:28cfac049a6a] in lemon
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/bin_heap.h
r463 r758 20 20 #define LEMON_BIN_HEAP_H 21 21 22 ///\ingroup auxdat22 ///\ingroup heaps 23 23 ///\file 24 ///\brief Binary Heap implementation.24 ///\brief Binary heap implementation. 25 25 26 26 #include <vector> … … 30 30 namespace lemon { 31 31 32 /// \ingroup auxdat32 /// \ingroup heaps 33 33 /// 34 /// \brief A Binary Heap implementation.34 /// \brief Binary heap data structure. 35 35 /// 36 ///This class implements the \e binary \e heap data structure. A \e heap 37 ///is a data structure for storing items with specified values called \e 38 ///priorities in such a way that finding the item with minimum priority is 39 ///efficient. \c Compare specifies the ordering of the priorities. In a heap 40 ///one can change the priority of an item, add or erase an item, etc. 36 /// This class implements the \e binary \e heap data structure. 37 /// It fully conforms to the \ref concepts::Heap "heap concept". 41 38 /// 42 /// \tparam _Prio Type of the priorityof the items.43 /// \tparam _ItemIntMap A read and writable Item int map, used internally44 /// to handle the cross references.45 /// \tparam _Compare A class for the ordering of the priorities. The46 /// default is \c std::less<_Prio>.47 /// 48 ///\sa FibHeap49 ///\sa Dijkstra 50 template <typename _Prio, typename _ItemIntMap,51 typename _Compare = std::less<_Prio> > 39 /// \tparam PR Type of the priorities of the items. 40 /// \tparam IM A read-writable item map with \c int values, used 41 /// internally to handle the cross references. 42 /// \tparam CMP A functor class for comparing the priorities. 43 /// The default is \c std::less<PR>. 44 #ifdef DOXYGEN 45 template <typename PR, typename IM, typename CMP> 46 #else 47 template <typename PR, typename IM, typename CMP = std::less<PR> > 48 #endif 52 49 class BinHeap { 53 54 50 public: 55 ///\e 56 typedef _ItemIntMap ItemIntMap; 57 ///\e 58 typedef _Prio Prio; 59 ///\e 51 52 /// Type of the item-int map. 53 typedef IM ItemIntMap; 54 /// Type of the priorities. 55 typedef PR Prio; 56 /// Type of the items stored in the heap. 60 57 typedef typename ItemIntMap::Key Item; 61 /// \e58 /// Type of the item-priority pairs. 62 59 typedef std::pair<Item,Prio> Pair; 63 /// \e64 typedef _CompareCompare;65 66 /// \brief Type to represent the items states.67 /// 68 /// Each Item element have a state associated to it. It maybe "in heap",69 /// "pre heap" or "postheap". The latter two are indifferent from the60 /// Functor type for comparing the priorities. 61 typedef CMP Compare; 62 63 /// \brief Type to represent the states of the items. 64 /// 65 /// Each item has a state associated to it. It can be "in heap", 66 /// "pre-heap" or "post-heap". The latter two are indifferent from the 70 67 /// heap's point of view, but may be useful to the user. 71 68 /// 72 /// The ItemIntMap \e should be initialized in such way that it maps73 /// PRE_HEAP (-1) to any element to be put in the heap...69 /// The item-int map must be initialized in such way that it assigns 70 /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap. 74 71 enum State { 75 IN_HEAP = 0, 76 PRE_HEAP = -1, 77 POST_HEAP = -2 72 IN_HEAP = 0, ///< = 0. 73 PRE_HEAP = -1, ///< = -1. 74 POST_HEAP = -2 ///< = -2. 78 75 }; 79 76 80 77 private: 81 std::vector<Pair> data;82 Compare comp;83 ItemIntMap & iim;78 std::vector<Pair> _data; 79 Compare _comp; 80 ItemIntMap &_iim; 84 81 85 82 public: 86 /// \brief The constructor. 87 /// 88 /// The constructor. 89 /// \param _iim should be given to the constructor, since it is used 90 /// internally to handle the cross references. The value of the map 91 /// should be PRE_HEAP (-1) for each element. 92 explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {} 93 94 /// \brief The constructor. 95 /// 96 /// The constructor. 97 /// \param _iim should be given to the constructor, since it is used 98 /// internally to handle the cross references. The value of the map 99 /// should be PRE_HEAP (-1) for each element. 100 /// 101 /// \param _comp The comparator function object. 102 BinHeap(ItemIntMap &_iim, const Compare &_comp) 103 : iim(_iim), comp(_comp) {} 104 105 106 /// The number of items stored in the heap. 107 /// 108 /// \brief Returns the number of items stored in the heap. 109 int size() const { return data.size(); } 110 111 /// \brief Checks if the heap stores no items. 112 /// 113 /// Returns \c true if and only if the heap stores no items. 114 bool empty() const { return data.empty(); } 115 116 /// \brief Make empty this heap. 117 /// 118 /// Make empty this heap. It does not change the cross reference map. 119 /// If you want to reuse what is not surely empty you should first clear 120 /// the heap and after that you should set the cross reference map for 121 /// each item to \c PRE_HEAP. 83 84 /// \brief Constructor. 85 /// 86 /// Constructor. 87 /// \param map A map that assigns \c int values to the items. 88 /// It is used internally to handle the cross references. 89 /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item. 90 explicit BinHeap(ItemIntMap &map) : _iim(map) {} 91 92 /// \brief Constructor. 93 /// 94 /// Constructor. 95 /// \param map A map that assigns \c int values to the items. 96 /// It is used internally to handle the cross references. 97 /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item. 98 /// \param comp The function object used for comparing the priorities. 99 BinHeap(ItemIntMap &map, const Compare &comp) 100 : _iim(map), _comp(comp) {} 101 102 103 /// \brief The number of items stored in the heap. 104 /// 105 /// This function returns the number of items stored in the heap. 106 int size() const { return _data.size(); } 107 108 /// \brief Check if the heap is empty. 109 /// 110 /// This function returns \c true if the heap is empty. 111 bool empty() const { return _data.empty(); } 112 113 /// \brief Make the heap empty. 114 /// 115 /// This functon makes the heap empty. 116 /// It does not change the cross reference map. If you want to reuse 117 /// a heap that is not surely empty, you should first clear it and 118 /// then you should set the cross reference map to \c PRE_HEAP 119 /// for each item. 122 120 void clear() { 123 data.clear();121 _data.clear(); 124 122 } 125 123 … … 127 125 static int parent(int i) { return (i-1)/2; } 128 126 129 static int second _child(int i) { return 2*i+2; }127 static int secondChild(int i) { return 2*i+2; } 130 128 bool less(const Pair &p1, const Pair &p2) const { 131 return comp(p1.second, p2.second);132 } 133 134 int bubble _up(int hole, Pair p) {129 return _comp(p1.second, p2.second); 130 } 131 132 int bubbleUp(int hole, Pair p) { 135 133 int par = parent(hole); 136 while( hole>0 && less(p, data[par]) ) {137 move( data[par],hole);134 while( hole>0 && less(p,_data[par]) ) { 135 move(_data[par],hole); 138 136 hole = par; 139 137 par = parent(hole); … … 143 141 } 144 142 145 int bubble _down(int hole, Pair p, int length) {146 int child = second _child(hole);143 int bubbleDown(int hole, Pair p, int length) { 144 int child = secondChild(hole); 147 145 while(child < length) { 148 if( less( data[child-1],data[child]) ) {146 if( less(_data[child-1], _data[child]) ) { 149 147 --child; 150 148 } 151 if( !less( data[child], p) )149 if( !less(_data[child], p) ) 152 150 goto ok; 153 move( data[child], hole);151 move(_data[child], hole); 154 152 hole = child; 155 child = second _child(hole);153 child = secondChild(hole); 156 154 } 157 155 child--; 158 if( child<length && less( data[child], p) ) {159 move( data[child], hole);156 if( child<length && less(_data[child], p) ) { 157 move(_data[child], hole); 160 158 hole=child; 161 159 } … … 166 164 167 165 void move(const Pair &p, int i) { 168 data[i] = p;169 iim.set(p.first, i);166 _data[i] = p; 167 _iim.set(p.first, i); 170 168 } 171 169 172 170 public: 171 173 172 /// \brief Insert a pair of item and priority into the heap. 174 173 /// 175 /// Adds \c p.first to the heap with priority \c p.second. 174 /// This function inserts \c p.first to the heap with priority 175 /// \c p.second. 176 176 /// \param p The pair to insert. 177 /// \pre \c p.first must not be stored in the heap. 177 178 void push(const Pair &p) { 178 int n = data.size(); 179 data.resize(n+1); 180 bubble_up(n, p); 181 } 182 183 /// \brief Insert an item into the heap with the given heap. 184 /// 185 /// Adds \c i to the heap with priority \c p. 179 int n = _data.size(); 180 _data.resize(n+1); 181 bubbleUp(n, p); 182 } 183 184 /// \brief Insert an item into the heap with the given priority. 185 /// 186 /// This function inserts the given item into the heap with the 187 /// given priority. 186 188 /// \param i The item to insert. 187 189 /// \param p The priority of the item. 190 /// \pre \e i must not be stored in the heap. 188 191 void push(const Item &i, const Prio &p) { push(Pair(i,p)); } 189 192 190 /// \brief Returns the item with minimum priority relative to \c Compare. 191 /// 192 /// This method returns the item with minimum priority relative to \c 193 /// Compare. 194 /// \pre The heap must be nonempty. 193 /// \brief Return the item having minimum priority. 194 /// 195 /// This function returns the item having minimum priority. 196 /// \pre The heap must be non-empty. 195 197 Item top() const { 196 return data[0].first;197 } 198 199 /// \brief Returns the minimum priority relative to \c Compare.200 /// 201 /// It returns the minimum priority relative to \c Compare.202 /// \pre The heap must be non empty.198 return _data[0].first; 199 } 200 201 /// \brief The minimum priority. 202 /// 203 /// This function returns the minimum priority. 204 /// \pre The heap must be non-empty. 203 205 Prio prio() const { 204 return data[0].second; 205 } 206 207 /// \brief Deletes the item with minimum priority relative to \c Compare. 208 /// 209 /// This method deletes the item with minimum priority relative to \c 210 /// Compare from the heap. 206 return _data[0].second; 207 } 208 209 /// \brief Remove the item having minimum priority. 210 /// 211 /// This function removes the item having minimum priority. 211 212 /// \pre The heap must be non-empty. 212 213 void pop() { 213 int n = data.size()-1;214 iim.set(data[0].first, POST_HEAP);214 int n = _data.size()-1; 215 _iim.set(_data[0].first, POST_HEAP); 215 216 if (n > 0) { 216 bubble_down(0, data[n], n); 217 } 218 data.pop_back(); 219 } 220 221 /// \brief Deletes \c i from the heap. 222 /// 223 /// This method deletes item \c i from the heap. 224 /// \param i The item to erase. 225 /// \pre The item should be in the heap. 217 bubbleDown(0, _data[n], n); 218 } 219 _data.pop_back(); 220 } 221 222 /// \brief Remove the given item from the heap. 223 /// 224 /// This function removes the given item from the heap if it is 225 /// already stored. 226 /// \param i The item to delete. 227 /// \pre \e i must be in the heap. 226 228 void erase(const Item &i) { 227 int h = iim[i];228 int n = data.size()-1;229 iim.set(data[h].first, POST_HEAP);229 int h = _iim[i]; 230 int n = _data.size()-1; 231 _iim.set(_data[h].first, POST_HEAP); 230 232 if( h < n ) { 231 if ( bubble _up(h,data[n]) == h) {232 bubble _down(h,data[n], n);233 if ( bubbleUp(h, _data[n]) == h) { 234 bubbleDown(h, _data[n], n); 233 235 } 234 236 } 235 data.pop_back(); 236 } 237 238 239 /// \brief Returns the priority of \c i. 240 /// 241 /// This function returns the priority of item \c i. 242 /// \pre \c i must be in the heap. 243 /// \param i The item. 237 _data.pop_back(); 238 } 239 240 /// \brief The priority of the given item. 241 /// 242 /// This function returns the priority of the given item. 243 /// \param i The item. 244 /// \pre \e i must be in the heap. 244 245 Prio operator[](const Item &i) const { 245 int idx = iim[i]; 246 return data[idx].second; 247 } 248 249 /// \brief \c i gets to the heap with priority \c p independently 250 /// if \c i was already there. 251 /// 252 /// This method calls \ref push(\c i, \c p) if \c i is not stored 253 /// in the heap and sets the priority of \c i to \c p otherwise. 246 int idx = _iim[i]; 247 return _data[idx].second; 248 } 249 250 /// \brief Set the priority of an item or insert it, if it is 251 /// not stored in the heap. 252 /// 253 /// This method sets the priority of the given item if it is 254 /// already stored in the heap. Otherwise it inserts the given 255 /// item into the heap with the given priority. 254 256 /// \param i The item. 255 257 /// \param p The priority. 256 258 void set(const Item &i, const Prio &p) { 257 int idx = iim[i];259 int idx = _iim[i]; 258 260 if( idx < 0 ) { 259 261 push(i,p); 260 262 } 261 else if( comp(p,data[idx].second) ) {262 bubble _up(idx, Pair(i,p));263 else if( _comp(p, _data[idx].second) ) { 264 bubbleUp(idx, Pair(i,p)); 263 265 } 264 266 else { 265 bubble_down(idx, Pair(i,p), data.size()); 266 } 267 } 268 269 /// \brief Decreases the priority of \c i to \c p. 270 /// 271 /// This method decreases the priority of item \c i to \c p. 272 /// \pre \c i must be stored in the heap with priority at least \c 273 /// p relative to \c Compare. 267 bubbleDown(idx, Pair(i,p), _data.size()); 268 } 269 } 270 271 /// \brief Decrease the priority of an item to the given value. 272 /// 273 /// This function decreases the priority of an item to the given value. 274 274 /// \param i The item. 275 275 /// \param p The priority. 276 /// \pre \e i must be stored in the heap with priority at least \e p. 276 277 void decrease(const Item &i, const Prio &p) { 277 int idx = iim[i]; 278 bubble_up(idx, Pair(i,p)); 279 } 280 281 /// \brief Increases the priority of \c i to \c p. 282 /// 283 /// This method sets the priority of item \c i to \c p. 284 /// \pre \c i must be stored in the heap with priority at most \c 285 /// p relative to \c Compare. 278 int idx = _iim[i]; 279 bubbleUp(idx, Pair(i,p)); 280 } 281 282 /// \brief Increase the priority of an item to the given value. 283 /// 284 /// This function increases the priority of an item to the given value. 286 285 /// \param i The item. 287 286 /// \param p The priority. 287 /// \pre \e i must be stored in the heap with priority at most \e p. 288 288 void increase(const Item &i, const Prio &p) { 289 int idx = iim[i];290 bubble _down(idx, Pair(i,p),data.size());291 } 292 293 /// \brief Return s if \c item is in, has already been in, or has294 /// never been in the heap.295 /// 296 /// This method returns PRE_HEAP if \c item has never been in the297 /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP298 /// otherwise. In the latter case it is possible that \c item will299 /// get backto the heap again.289 int idx = _iim[i]; 290 bubbleDown(idx, Pair(i,p), _data.size()); 291 } 292 293 /// \brief Return the state of an item. 294 /// 295 /// This method returns \c PRE_HEAP if the given item has never 296 /// been in the heap, \c IN_HEAP if it is in the heap at the moment, 297 /// and \c POST_HEAP otherwise. 298 /// In the latter case it is possible that the item will get back 299 /// to the heap again. 300 300 /// \param i The item. 301 301 State state(const Item &i) const { 302 int s = iim[i];302 int s = _iim[i]; 303 303 if( s>=0 ) 304 304 s=0; … … 306 306 } 307 307 308 /// \brief Set s the state of the \citem in the heap.309 /// 310 /// Sets the state of the \c item in the heap. It can be used to311 /// manually clear the heap when it is important to achive the312 /// better time complexity.308 /// \brief Set the state of an item in the heap. 309 /// 310 /// This function sets the state of the given item in the heap. 311 /// It can be used to manually clear the heap when it is important 312 /// to achive better time complexity. 313 313 /// \param i The item. 314 314 /// \param st The state. It should not be \c IN_HEAP. … … 320 320 erase(i); 321 321 } 322 iim[i] = st;322 _iim[i] = st; 323 323 break; 324 324 case IN_HEAP: … … 327 327 } 328 328 329 /// \brief Replaces an item in the heap. 330 /// 331 /// The \c i item is replaced with \c j item. The \c i item should 332 /// be in the heap, while the \c j should be out of the heap. The 333 /// \c i item will out of the heap and \c j will be in the heap 334 /// with the same prioriority as prevoiusly the \c i item. 329 /// \brief Replace an item in the heap. 330 /// 331 /// This function replaces item \c i with item \c j. 332 /// Item \c i must be in the heap, while \c j must be out of the heap. 333 /// After calling this method, item \c i will be out of the 334 /// heap and \c j will be in the heap with the same prioriority 335 /// as item \c i had before. 335 336 void replace(const Item& i, const Item& j) { 336 int idx = iim[i];337 iim.set(i,iim[j]);338 iim.set(j, idx);339 data[idx].first = j;337 int idx = _iim[i]; 338 _iim.set(i, _iim[j]); 339 _iim.set(j, idx); 340 _data[idx].first = j; 340 341 } 341 342
Note: See TracChangeset
for help on using the changeset viewer.