18 #define LEMON_BIN_HEAP_H |
18 #define LEMON_BIN_HEAP_H |
19 |
19 |
20 ///\ingroup auxdat |
20 ///\ingroup auxdat |
21 ///\file |
21 ///\file |
22 ///\brief Binary Heap implementation. |
22 ///\brief Binary Heap implementation. |
23 ///\todo It should be documented. |
|
24 |
23 |
25 #include <vector> |
24 #include <vector> |
26 #include <utility> |
25 #include <utility> |
27 #include <functional> |
26 #include <functional> |
28 |
27 |
29 namespace lemon { |
28 namespace lemon { |
30 |
29 |
31 /// \addtogroup auxdat |
30 /// \addtogroup auxdat |
32 /// @{ |
31 /// @{ |
33 |
32 |
34 /// A Binary Heap implementation. |
33 /// A Binary Heap implementation. |
35 |
34 |
36 ///\todo Please document... |
35 ///This class implements the \e binary \e heap data structure. A \e heap |
|
36 ///is a data structure for storing items with specified values called \e |
|
37 ///priorities in such a way that finding the item with minimum priority is |
|
38 ///efficient. \c Compare specifies the ordering of the priorities. In a heap |
|
39 ///one can change the priority of an item, add or erase an item, etc. |
|
40 /// |
|
41 ///\param Item Type of the items to be stored. |
|
42 ///\param Prio Type of the priority of the items. |
|
43 ///\param ItemIntMap A read and writable Item int map, used internally |
|
44 ///to handle the cross references. |
|
45 ///\param Compare A class for the ordering of the priorities. The |
|
46 ///default is \c std::less<Prio>. |
37 /// |
47 /// |
38 ///\sa FibHeap |
48 ///\sa FibHeap |
39 ///\sa Dijkstra |
49 ///\sa Dijkstra |
40 template <typename Item, typename Prio, typename ItemIntMap, |
50 template <typename Item, typename Prio, typename ItemIntMap, |
41 typename Compare = std::less<Prio> > |
51 typename Compare = std::less<Prio> > |
70 Compare comp; |
80 Compare comp; |
71 // FIXME: jo ez igy??? |
81 // FIXME: jo ez igy??? |
72 ItemIntMap &iim; |
82 ItemIntMap &iim; |
73 |
83 |
74 public: |
84 public: |
75 ///\e |
85 ///The constructor |
|
86 |
|
87 /** |
|
88 \c _iim should be given to the constructor, since it is used |
|
89 internally to handle the cross references. |
|
90 */ |
76 explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {} |
91 explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {} |
77 ///\e |
92 |
|
93 ///The constructor |
|
94 |
|
95 /** |
|
96 \c _iim should be given to the constructor, since it is used |
|
97 internally to handle the cross references. \c _comp is an |
|
98 object for ordering of the priorities. |
|
99 */ |
78 BinHeap(ItemIntMap &_iim, const Compare &_comp) |
100 BinHeap(ItemIntMap &_iim, const Compare &_comp) |
79 : iim(_iim), comp(_comp) {} |
101 : iim(_iim), comp(_comp) {} |
80 |
102 |
81 |
103 |
82 ///\e |
104 ///The number of items stored in the heap. |
|
105 |
|
106 /** |
|
107 Returns the number of items stored in the heap. |
|
108 */ |
83 int size() const { return data.size(); } |
109 int size() const { return data.size(); } |
84 ///\e |
110 |
|
111 ///Checks if the heap stores no items. |
|
112 |
|
113 /** |
|
114 Returns \c true if and only if the heap stores no items. |
|
115 */ |
85 bool empty() const { return data.empty(); } |
116 bool empty() const { return data.empty(); } |
86 |
117 |
87 private: |
118 private: |
88 static int parent(int i) { return (i-1)/2; } |
119 static int parent(int i) { return (i-1)/2; } |
89 static int second_child(int i) { return 2*i+2; } |
120 static int second_child(int i) { return 2*i+2; } |
109 data.pop_back(); |
140 data.pop_back(); |
110 } |
141 } |
111 } |
142 } |
112 |
143 |
113 public: |
144 public: |
114 ///\e |
145 ///Adds \c p.first to the heap with priority \c p.second. |
|
146 |
|
147 /** |
|
148 Adds \c p.first to the heap with priority \c p.second. |
|
149 \c p.first must not be stored in the heap. |
|
150 */ |
115 void push(const PairType &p) { |
151 void push(const PairType &p) { |
116 int n = data.size(); |
152 int n = data.size(); |
117 data.resize(n+1); |
153 data.resize(n+1); |
118 bubble_up(n, p); |
154 bubble_up(n, p); |
119 } |
155 } |
120 ///\e |
156 |
|
157 ///Adds \c i to the heap with priority \c p. |
|
158 |
|
159 /** |
|
160 Adds \c i to the heap with priority \c p. |
|
161 \pre \c i must not be stored in the heap. |
|
162 */ |
121 void push(const Item &i, const Prio &p) { push(PairType(i,p)); } |
163 void push(const Item &i, const Prio &p) { push(PairType(i,p)); } |
122 |
164 |
123 ///\e |
165 ///Returns the item with minimum priority relative to \c Compare. |
|
166 |
|
167 /** |
|
168 This method returns the item with minimum priority relative to \c |
|
169 Compare. |
|
170 \pre The heap must be nonempty. |
|
171 */ |
124 Item top() const { |
172 Item top() const { |
125 return data[0].first; |
173 return data[0].first; |
126 } |
174 } |
127 /// Returns the prio of the top element of the heap. |
175 |
|
176 ///Returns the minimum priority relative to \c Compare. |
|
177 |
|
178 /** |
|
179 It returns the minimum priority relative to \c Compare. |
|
180 \pre The heap must be nonempty. |
|
181 */ |
128 Prio prio() const { |
182 Prio prio() const { |
129 return data[0].second; |
183 return data[0].second; |
130 } |
184 } |
131 |
185 |
132 ///\e |
186 ///Deletes the item with minimum priority relative to \c Compare. |
|
187 |
|
188 /** |
|
189 This method deletes the item with minimum priority relative to \c |
|
190 Compare from the heap. |
|
191 \pre The heap must be non-empty. |
|
192 */ |
133 void pop() { |
193 void pop() { |
134 rmidx(0); |
194 rmidx(0); |
135 } |
195 } |
136 |
196 |
137 ///\e |
197 ///Deletes \c i from the heap. |
|
198 |
|
199 /** |
|
200 This method deletes item \c i from the heap, if \c i was |
|
201 already stored in the heap. |
|
202 */ |
138 void erase(const Item &i) { |
203 void erase(const Item &i) { |
139 rmidx(iim[i]); |
204 rmidx(iim[i]); |
140 } |
205 } |
141 |
206 |
142 ///\e |
207 |
|
208 ///Returns the priority of \c i. |
|
209 |
|
210 /** |
|
211 This function returns the priority of item \c i. |
|
212 \pre \c i must be in the heap. |
|
213 */ |
143 Prio operator[](const Item &i) const { |
214 Prio operator[](const Item &i) const { |
144 int idx = iim[i]; |
215 int idx = iim[i]; |
145 return data[idx].second; |
216 return data[idx].second; |
146 } |
217 } |
147 |
218 |
148 ///\e |
219 ///\c i gets to the heap with priority \c p independently if \c i was already there. |
|
220 |
|
221 /** |
|
222 This method calls \ref push(\c i, \c p) if \c i is not stored |
|
223 in the heap and sets the priority of \c i to \c p otherwise. |
|
224 */ |
149 void set(const Item &i, const Prio &p) { |
225 void set(const Item &i, const Prio &p) { |
150 int idx = iim[i]; |
226 int idx = iim[i]; |
151 if( idx < 0 ) { |
227 if( idx < 0 ) { |
152 push(i,p); |
228 push(i,p); |
153 } |
229 } |
157 else { |
233 else { |
158 bubble_down(idx, PairType(i,p), data.size()); |
234 bubble_down(idx, PairType(i,p), data.size()); |
159 } |
235 } |
160 } |
236 } |
161 |
237 |
162 ///\e |
238 ///Decreases the priority of \c i to \c p. |
|
239 |
|
240 /** |
|
241 This method decreases the priority of item \c i to \c p. |
|
242 \pre \c i must be stored in the heap with priority at least \c |
|
243 p relative to \c Compare. |
|
244 */ |
163 void decrease(const Item &i, const Prio &p) { |
245 void decrease(const Item &i, const Prio &p) { |
164 int idx = iim[i]; |
246 int idx = iim[i]; |
165 bubble_up(idx, PairType(i,p)); |
247 bubble_up(idx, PairType(i,p)); |
166 } |
248 } |
167 ///\e |
249 |
|
250 ///Increases the priority of \c i to \c p. |
|
251 |
|
252 /** |
|
253 This method sets the priority of item \c i to \c p. |
|
254 \pre \c i must be stored in the heap with priority at most \c |
|
255 p relative to \c Compare. |
|
256 */ |
168 void increase(const Item &i, const Prio &p) { |
257 void increase(const Item &i, const Prio &p) { |
169 int idx = iim[i]; |
258 int idx = iim[i]; |
170 bubble_down(idx, PairType(i,p), data.size()); |
259 bubble_down(idx, PairType(i,p), data.size()); |
171 } |
260 } |
172 |
261 |
173 ///\e |
262 ///Returns if \c item is in, has already been in, or has never been in the heap. |
|
263 |
|
264 /** |
|
265 This method returns PRE_HEAP if \c item has never been in the |
|
266 heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP |
|
267 otherwise. In the latter case it is possible that \c item will |
|
268 get back to the heap again. |
|
269 */ |
174 state_enum state(const Item &i) const { |
270 state_enum state(const Item &i) const { |
175 int s = iim[i]; |
271 int s = iim[i]; |
176 if( s>=0 ) |
272 if( s>=0 ) |
177 s=0; |
273 s=0; |
178 return state_enum(s); |
274 return state_enum(s); |