2 * src/lemon/bin_heap.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #ifndef LEMON_BIN_HEAP_H
18 #define LEMON_BIN_HEAP_H
22 ///\brief Binary Heap implementation.
30 /// \addtogroup auxdat
33 /// A Binary Heap implementation.
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.
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>.
50 template <typename Item, typename Prio, typename ItemIntMap,
51 typename Compare = std::less<Prio> >
55 typedef Item ItemType;
56 // FIXME: stl-ben nem ezt hivjak value_type -nak, hanem a kovetkezot...
57 typedef Prio PrioType;
58 typedef std::pair<ItemType,PrioType> PairType;
59 typedef ItemIntMap ItemIntMapType;
60 typedef Compare PrioCompare;
63 * Each Item element have a state associated to it. It may be "in heap",
64 * "pre heap" or "post heap". The later two are indifferent from the
65 * heap's point of view, but may be useful to the user.
67 * The ItemIntMap _should_ be initialized in such way, that it maps
68 * PRE_HEAP (-1) to any element to be put in the heap...
70 ///\todo it is used nowhere
79 std::vector<PairType> data;
81 // FIXME: jo ez igy???
88 \c _iim should be given to the constructor, since it is used
89 internally to handle the cross references.
91 explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {}
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.
100 BinHeap(ItemIntMap &_iim, const Compare &_comp)
101 : iim(_iim), comp(_comp) {}
104 ///The number of items stored in the heap.
107 Returns the number of items stored in the heap.
109 int size() const { return data.size(); }
111 ///Checks if the heap stores no items.
114 Returns \c true if and only if the heap stores no items.
116 bool empty() const { return data.empty(); }
119 static int parent(int i) { return (i-1)/2; }
120 static int second_child(int i) { return 2*i+2; }
121 bool less(const PairType &p1, const PairType &p2) const {
122 return comp(p1.second, p2.second);
125 int bubble_up(int hole, PairType p);
126 int bubble_down(int hole, PairType p, int length);
128 void move(const PairType &p, int i) {
134 int n = data.size()-1;
136 iim.set(data[h].first, POST_HEAP);
138 bubble_down(h, data[n], n);
145 ///Adds \c p.first to the heap with priority \c p.second.
148 Adds \c p.first to the heap with priority \c p.second.
149 \c p.first must not be stored in the heap.
151 void push(const PairType &p) {
157 ///Adds \c i to the heap with priority \c p.
160 Adds \c i to the heap with priority \c p.
161 \pre \c i must not be stored in the heap.
163 void push(const Item &i, const Prio &p) { push(PairType(i,p)); }
165 ///Returns the item with minimum priority relative to \c Compare.
168 This method returns the item with minimum priority relative to \c
170 \pre The heap must be nonempty.
173 return data[0].first;
176 ///Returns the minimum priority relative to \c Compare.
179 It returns the minimum priority relative to \c Compare.
180 \pre The heap must be nonempty.
183 return data[0].second;
186 ///Deletes the item with minimum priority relative to \c Compare.
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.
197 ///Deletes \c i from the heap.
200 This method deletes item \c i from the heap, if \c i was
201 already stored in the heap.
203 void erase(const Item &i) {
208 ///Returns the priority of \c i.
211 This function returns the priority of item \c i.
212 \pre \c i must be in the heap.
214 Prio operator[](const Item &i) const {
216 return data[idx].second;
219 ///\c i gets to the heap with priority \c p independently if \c i was already there.
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.
225 void set(const Item &i, const Prio &p) {
230 else if( comp(p, data[idx].second) ) {
231 bubble_up(idx, PairType(i,p));
234 bubble_down(idx, PairType(i,p), data.size());
238 ///Decreases the priority of \c i to \c p.
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.
245 void decrease(const Item &i, const Prio &p) {
247 bubble_up(idx, PairType(i,p));
250 ///Increases the priority of \c i to \c p.
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.
257 void increase(const Item &i, const Prio &p) {
259 bubble_down(idx, PairType(i,p), data.size());
262 ///Returns if \c item is in, has already been in, or has never been in the heap.
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.
270 state_enum state(const Item &i) const {
274 return state_enum(s);
280 template <typename K, typename V, typename M, typename C>
281 int BinHeap<K,V,M,C>::bubble_up(int hole, PairType p) {
282 int par = parent(hole);
283 while( hole>0 && less(p,data[par]) ) {
284 move(data[par],hole);
292 template <typename K, typename V, typename M, typename C>
293 int BinHeap<K,V,M,C>::bubble_down(int hole, PairType p, int length) {
294 int child = second_child(hole);
295 while(child < length) {
296 if( less(data[child-1], data[child]) ) {
299 if( !less(data[child], p) )
301 move(data[child], hole);
303 child = second_child(hole);
306 if( child<length && less(data[child], p) ) {
307 move(data[child], hole);
319 #endif // LEMON_BIN_HEAP_H