19 #ifndef LEMON_BIN_HEAP_H |
19 #ifndef LEMON_BIN_HEAP_H |
20 #define LEMON_BIN_HEAP_H |
20 #define LEMON_BIN_HEAP_H |
21 |
21 |
22 ///\ingroup auxdat |
22 ///\ingroup auxdat |
23 ///\file |
23 ///\file |
24 ///\brief Binary Heap implementation. |
24 ///\brief Binary heap implementation. |
25 |
25 |
26 #include <vector> |
26 #include <vector> |
27 #include <utility> |
27 #include <utility> |
28 #include <functional> |
28 #include <functional> |
29 |
29 |
30 namespace lemon { |
30 namespace lemon { |
31 |
31 |
32 ///\ingroup auxdat |
32 /// \ingroup auxdat |
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. |
36 /// This class implements the \e binary \e heap data structure. |
|
37 /// It fully conforms to the \ref concepts::Heap "heap concept". |
37 /// |
38 /// |
38 ///A \e heap is a data structure for storing items with specified values |
39 /// \tparam PR Type of the priorities of the items. |
39 ///called \e priorities in such a way that finding the item with minimum |
40 /// \tparam IM A read-writable item map with \c int values, used |
40 ///priority is efficient. \c CMP specifies the ordering of the priorities. |
41 /// internally to handle the cross references. |
41 ///In a heap one can change the priority of an item, add or erase an |
42 /// \tparam CMP A functor class for comparing the priorities. |
42 ///item, etc. |
43 /// The default is \c std::less<PR>. |
43 /// |
44 #ifdef DOXYGEN |
44 ///\tparam PR Type of the priority of the items. |
45 template <typename PR, typename IM, typename CMP> |
45 ///\tparam IM A read and writable item map with int values, used internally |
46 #else |
46 ///to handle the cross references. |
|
47 ///\tparam CMP A functor class for the ordering of the priorities. |
|
48 ///The default is \c std::less<PR>. |
|
49 /// |
|
50 ///\sa FibHeap |
|
51 ///\sa Dijkstra |
|
52 template <typename PR, typename IM, typename CMP = std::less<PR> > |
47 template <typename PR, typename IM, typename CMP = std::less<PR> > |
|
48 #endif |
53 class BinHeap { |
49 class BinHeap { |
54 |
|
55 public: |
50 public: |
56 ///\e |
51 |
|
52 /// Type of the item-int map. |
57 typedef IM ItemIntMap; |
53 typedef IM ItemIntMap; |
58 ///\e |
54 /// Type of the priorities. |
59 typedef PR Prio; |
55 typedef PR Prio; |
60 ///\e |
56 /// Type of the items stored in the heap. |
61 typedef typename ItemIntMap::Key Item; |
57 typedef typename ItemIntMap::Key Item; |
62 ///\e |
58 /// Type of the item-priority pairs. |
63 typedef std::pair<Item,Prio> Pair; |
59 typedef std::pair<Item,Prio> Pair; |
64 ///\e |
60 /// Functor type for comparing the priorities. |
65 typedef CMP Compare; |
61 typedef CMP Compare; |
66 |
62 |
67 /// \brief Type to represent the items states. |
63 /// \brief Type to represent the states of the items. |
68 /// |
64 /// |
69 /// Each Item element have a state associated to it. It may be "in heap", |
65 /// Each item has a state associated to it. It can be "in heap", |
70 /// "pre heap" or "post heap". The latter two are indifferent from the |
66 /// "pre-heap" or "post-heap". The latter two are indifferent from the |
71 /// heap's point of view, but may be useful to the user. |
67 /// heap's point of view, but may be useful to the user. |
72 /// |
68 /// |
73 /// The item-int map must be initialized in such way that it assigns |
69 /// The item-int map must be initialized in such way that it assigns |
74 /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap. |
70 /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap. |
75 enum State { |
71 enum State { |
82 std::vector<Pair> _data; |
78 std::vector<Pair> _data; |
83 Compare _comp; |
79 Compare _comp; |
84 ItemIntMap &_iim; |
80 ItemIntMap &_iim; |
85 |
81 |
86 public: |
82 public: |
87 /// \brief The constructor. |
83 |
88 /// |
84 /// \brief Constructor. |
89 /// The constructor. |
85 /// |
90 /// \param map should be given to the constructor, since it is used |
86 /// Constructor. |
91 /// internally to handle the cross references. The value of the map |
87 /// \param map A map that assigns \c int values to the items. |
92 /// must be \c PRE_HEAP (<tt>-1</tt>) for every item. |
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. |
93 explicit BinHeap(ItemIntMap &map) : _iim(map) {} |
90 explicit BinHeap(ItemIntMap &map) : _iim(map) {} |
94 |
91 |
95 /// \brief The constructor. |
92 /// \brief Constructor. |
96 /// |
93 /// |
97 /// The constructor. |
94 /// Constructor. |
98 /// \param map should be given to the constructor, since it is used |
95 /// \param map A map that assigns \c int values to the items. |
99 /// internally to handle the cross references. The value of the map |
96 /// It is used internally to handle the cross references. |
100 /// should be PRE_HEAP (-1) for each element. |
97 /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item. |
101 /// |
98 /// \param comp The function object used for comparing the priorities. |
102 /// \param comp The comparator function object. |
|
103 BinHeap(ItemIntMap &map, const Compare &comp) |
99 BinHeap(ItemIntMap &map, const Compare &comp) |
104 : _iim(map), _comp(comp) {} |
100 : _iim(map), _comp(comp) {} |
105 |
101 |
106 |
102 |
107 /// The number of items stored in the heap. |
103 /// \brief The number of items stored in the heap. |
108 /// |
104 /// |
109 /// \brief Returns the number of items stored in the heap. |
105 /// This function returns the number of items stored in the heap. |
110 int size() const { return _data.size(); } |
106 int size() const { return _data.size(); } |
111 |
107 |
112 /// \brief Checks if the heap stores no items. |
108 /// \brief Check if the heap is empty. |
113 /// |
109 /// |
114 /// Returns \c true if and only if the heap stores no items. |
110 /// This function returns \c true if the heap is empty. |
115 bool empty() const { return _data.empty(); } |
111 bool empty() const { return _data.empty(); } |
116 |
112 |
117 /// \brief Make empty this heap. |
113 /// \brief Make the heap empty. |
118 /// |
114 /// |
119 /// Make empty this heap. It does not change the cross reference map. |
115 /// This functon makes the heap empty. |
120 /// If you want to reuse what is not surely empty you should first clear |
116 /// It does not change the cross reference map. If you want to reuse |
121 /// the heap and after that you should set the cross reference map for |
117 /// a heap that is not surely empty, you should first clear it and |
122 /// each item to \c PRE_HEAP. |
118 /// then you should set the cross reference map to \c PRE_HEAP |
|
119 /// for each item. |
123 void clear() { |
120 void clear() { |
124 _data.clear(); |
121 _data.clear(); |
125 } |
122 } |
126 |
123 |
127 private: |
124 private: |
169 _data[i] = p; |
166 _data[i] = p; |
170 _iim.set(p.first, i); |
167 _iim.set(p.first, i); |
171 } |
168 } |
172 |
169 |
173 public: |
170 public: |
|
171 |
174 /// \brief Insert a pair of item and priority into the heap. |
172 /// \brief Insert a pair of item and priority into the heap. |
175 /// |
173 /// |
176 /// 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. |
177 /// \param p The pair to insert. |
176 /// \param p The pair to insert. |
|
177 /// \pre \c p.first must not be stored in the heap. |
178 void push(const Pair &p) { |
178 void push(const Pair &p) { |
179 int n = _data.size(); |
179 int n = _data.size(); |
180 _data.resize(n+1); |
180 _data.resize(n+1); |
181 bubble_up(n, p); |
181 bubble_up(n, p); |
182 } |
182 } |
183 |
183 |
184 /// \brief Insert an item into the heap with the given heap. |
184 /// \brief Insert an item into the heap with the given priority. |
185 /// |
185 /// |
186 /// Adds \c i to the heap with priority \c p. |
186 /// This function inserts the given item into the heap with the |
|
187 /// given priority. |
187 /// \param i The item to insert. |
188 /// \param i The item to insert. |
188 /// \param p The priority of the item. |
189 /// \param p The priority of the item. |
|
190 /// \pre \e i must not be stored in the heap. |
189 void push(const Item &i, const Prio &p) { push(Pair(i,p)); } |
191 void push(const Item &i, const Prio &p) { push(Pair(i,p)); } |
190 |
192 |
191 /// \brief Returns the item with minimum priority relative to \c Compare. |
193 /// \brief Return the item having minimum priority. |
192 /// |
194 /// |
193 /// This method returns the item with minimum priority relative to \c |
195 /// This function returns the item having minimum priority. |
194 /// Compare. |
196 /// \pre The heap must be non-empty. |
195 /// \pre The heap must be nonempty. |
|
196 Item top() const { |
197 Item top() const { |
197 return _data[0].first; |
198 return _data[0].first; |
198 } |
199 } |
199 |
200 |
200 /// \brief Returns the minimum priority relative to \c Compare. |
201 /// \brief The minimum priority. |
201 /// |
202 /// |
202 /// It returns the minimum priority relative to \c Compare. |
203 /// This function returns the minimum priority. |
203 /// \pre The heap must be nonempty. |
204 /// \pre The heap must be non-empty. |
204 Prio prio() const { |
205 Prio prio() const { |
205 return _data[0].second; |
206 return _data[0].second; |
206 } |
207 } |
207 |
208 |
208 /// \brief Deletes the item with minimum priority relative to \c Compare. |
209 /// \brief Remove the item having minimum priority. |
209 /// |
210 /// |
210 /// This method deletes the item with minimum priority relative to \c |
211 /// This function removes the item having minimum priority. |
211 /// Compare from the heap. |
|
212 /// \pre The heap must be non-empty. |
212 /// \pre The heap must be non-empty. |
213 void pop() { |
213 void pop() { |
214 int n = _data.size()-1; |
214 int n = _data.size()-1; |
215 _iim.set(_data[0].first, POST_HEAP); |
215 _iim.set(_data[0].first, POST_HEAP); |
216 if (n > 0) { |
216 if (n > 0) { |
217 bubble_down(0, _data[n], n); |
217 bubble_down(0, _data[n], n); |
218 } |
218 } |
219 _data.pop_back(); |
219 _data.pop_back(); |
220 } |
220 } |
221 |
221 |
222 /// \brief Deletes \c i from the heap. |
222 /// \brief Remove the given item from the heap. |
223 /// |
223 /// |
224 /// This method deletes item \c i from the heap. |
224 /// This function removes the given item from the heap if it is |
225 /// \param i The item to erase. |
225 /// already stored. |
226 /// \pre The item should be in the heap. |
226 /// \param i The item to delete. |
|
227 /// \pre \e i must be in the heap. |
227 void erase(const Item &i) { |
228 void erase(const Item &i) { |
228 int h = _iim[i]; |
229 int h = _iim[i]; |
229 int n = _data.size()-1; |
230 int n = _data.size()-1; |
230 _iim.set(_data[h].first, POST_HEAP); |
231 _iim.set(_data[h].first, POST_HEAP); |
231 if( h < n ) { |
232 if( h < n ) { |
234 } |
235 } |
235 } |
236 } |
236 _data.pop_back(); |
237 _data.pop_back(); |
237 } |
238 } |
238 |
239 |
239 |
240 /// \brief The priority of the given item. |
240 /// \brief Returns the priority of \c i. |
241 /// |
241 /// |
242 /// This function returns the priority of the given item. |
242 /// This function returns the priority of item \c i. |
243 /// \param i The item. |
243 /// \param i The item. |
244 /// \pre \e i must be in the heap. |
244 /// \pre \c i must be in the heap. |
|
245 Prio operator[](const Item &i) const { |
245 Prio operator[](const Item &i) const { |
246 int idx = _iim[i]; |
246 int idx = _iim[i]; |
247 return _data[idx].second; |
247 return _data[idx].second; |
248 } |
248 } |
249 |
249 |
250 /// \brief \c i gets to the heap with priority \c p independently |
250 /// \brief Set the priority of an item or insert it, if it is |
251 /// if \c i was already there. |
251 /// not stored in the heap. |
252 /// |
252 /// |
253 /// This method calls \ref push(\c i, \c p) if \c i is not stored |
253 /// This method sets the priority of the given item if it is |
254 /// in the heap and sets the priority of \c i to \c p otherwise. |
254 /// already stored in the heap. Otherwise it inserts the given |
|
255 /// item into the heap with the given priority. |
255 /// \param i The item. |
256 /// \param i The item. |
256 /// \param p The priority. |
257 /// \param p The priority. |
257 void set(const Item &i, const Prio &p) { |
258 void set(const Item &i, const Prio &p) { |
258 int idx = _iim[i]; |
259 int idx = _iim[i]; |
259 if( idx < 0 ) { |
260 if( idx < 0 ) { |
265 else { |
266 else { |
266 bubble_down(idx, Pair(i,p), _data.size()); |
267 bubble_down(idx, Pair(i,p), _data.size()); |
267 } |
268 } |
268 } |
269 } |
269 |
270 |
270 /// \brief Decreases the priority of \c i to \c p. |
271 /// \brief Decrease the priority of an item to the given value. |
271 /// |
272 /// |
272 /// This method decreases the priority of item \c i to \c p. |
273 /// This function decreases the priority of an item to the given value. |
273 /// \param i The item. |
274 /// \param i The item. |
274 /// \param p The priority. |
275 /// \param p The priority. |
275 /// \pre \c i must be stored in the heap with priority at least \c |
276 /// \pre \e i must be stored in the heap with priority at least \e p. |
276 /// p relative to \c Compare. |
|
277 void decrease(const Item &i, const Prio &p) { |
277 void decrease(const Item &i, const Prio &p) { |
278 int idx = _iim[i]; |
278 int idx = _iim[i]; |
279 bubble_up(idx, Pair(i,p)); |
279 bubble_up(idx, Pair(i,p)); |
280 } |
280 } |
281 |
281 |
282 /// \brief Increases the priority of \c i to \c p. |
282 /// \brief Increase the priority of an item to the given value. |
283 /// |
283 /// |
284 /// This method sets the priority of item \c i to \c p. |
284 /// This function increases the priority of an item to the given value. |
285 /// \param i The item. |
285 /// \param i The item. |
286 /// \param p The priority. |
286 /// \param p The priority. |
287 /// \pre \c i must be stored in the heap with priority at most \c |
287 /// \pre \e i must be stored in the heap with priority at most \e p. |
288 /// p relative to \c Compare. |
|
289 void increase(const Item &i, const Prio &p) { |
288 void increase(const Item &i, const Prio &p) { |
290 int idx = _iim[i]; |
289 int idx = _iim[i]; |
291 bubble_down(idx, Pair(i,p), _data.size()); |
290 bubble_down(idx, Pair(i,p), _data.size()); |
292 } |
291 } |
293 |
292 |
294 /// \brief Returns if \c item is in, has already been in, or has |
293 /// \brief Return the state of an item. |
295 /// never been in the heap. |
294 /// |
296 /// |
295 /// This method returns \c PRE_HEAP if the given item has never |
297 /// This method returns PRE_HEAP if \c item has never been in the |
296 /// been in the heap, \c IN_HEAP if it is in the heap at the moment, |
298 /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP |
297 /// and \c POST_HEAP otherwise. |
299 /// otherwise. In the latter case it is possible that \c item will |
298 /// In the latter case it is possible that the item will get back |
300 /// get back to the heap again. |
299 /// to the heap again. |
301 /// \param i The item. |
300 /// \param i The item. |
302 State state(const Item &i) const { |
301 State state(const Item &i) const { |
303 int s = _iim[i]; |
302 int s = _iim[i]; |
304 if( s>=0 ) |
303 if( s>=0 ) |
305 s=0; |
304 s=0; |
306 return State(s); |
305 return State(s); |
307 } |
306 } |
308 |
307 |
309 /// \brief Sets the state of the \c item in the heap. |
308 /// \brief Set the state of an item in the heap. |
310 /// |
309 /// |
311 /// Sets the state of the \c item in the heap. It can be used to |
310 /// This function sets the state of the given item in the heap. |
312 /// manually clear the heap when it is important to achive the |
311 /// It can be used to manually clear the heap when it is important |
313 /// better time complexity. |
312 /// to achive better time complexity. |
314 /// \param i The item. |
313 /// \param i The item. |
315 /// \param st The state. It should not be \c IN_HEAP. |
314 /// \param st The state. It should not be \c IN_HEAP. |
316 void state(const Item& i, State st) { |
315 void state(const Item& i, State st) { |
317 switch (st) { |
316 switch (st) { |
318 case POST_HEAP: |
317 case POST_HEAP: |
325 case IN_HEAP: |
324 case IN_HEAP: |
326 break; |
325 break; |
327 } |
326 } |
328 } |
327 } |
329 |
328 |
330 /// \brief Replaces an item in the heap. |
329 /// \brief Replace an item in the heap. |
331 /// |
330 /// |
332 /// The \c i item is replaced with \c j item. The \c i item should |
331 /// This function replaces item \c i with item \c j. |
333 /// be in the heap, while the \c j should be out of the heap. The |
332 /// Item \c i must be in the heap, while \c j must be out of the heap. |
334 /// \c i item will out of the heap and \c j will be in the heap |
333 /// After calling this method, item \c i will be out of the |
335 /// with the same prioriority as prevoiusly the \c i item. |
334 /// heap and \c j will be in the heap with the same prioriority |
|
335 /// as item \c i had before. |
336 void replace(const Item& i, const Item& j) { |
336 void replace(const Item& i, const Item& j) { |
337 int idx = _iim[i]; |
337 int idx = _iim[i]; |
338 _iim.set(i, _iim[j]); |
338 _iim.set(i, _iim[j]); |
339 _iim.set(j, idx); |
339 _iim.set(j, idx); |
340 _data[idx].first = j; |
340 _data[idx].first = j; |