gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Smarter bubbleDown() in K-ary heaps (#301)
0 2 0
default
2 files changed with 37 insertions and 43 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_FOURARY_HEAP_H
20 20
#define LEMON_FOURARY_HEAP_H
21 21

	
22 22
///\ingroup heaps
23 23
///\file
24 24
///\brief Fourary heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <utility>
28 28
#include <functional>
29 29

	
30 30
namespace lemon {
31 31

	
32 32
  /// \ingroup heaps
33 33
  ///
34 34
  ///\brief Fourary heap data structure.
35 35
  ///
36 36
  /// This class implements the \e fourary \e heap data structure.
37 37
  /// It fully conforms to the \ref concepts::Heap "heap concept".
38 38
  ///
39 39
  /// The fourary heap is a specialization of the \ref KaryHeap "K-ary heap"
40 40
  /// for <tt>K=4</tt>. It is similar to the \ref BinHeap "binary heap",
41 41
  /// but its nodes have at most four children, instead of two.
42 42
  ///
43 43
  /// \tparam PR Type of the priorities of the items.
44 44
  /// \tparam IM A read-writable item map with \c int values, used
45 45
  /// internally to handle the cross references.
46 46
  /// \tparam CMP A functor class for comparing the priorities.
47 47
  /// The default is \c std::less<PR>.
48 48
  ///
49 49
  ///\sa BinHeap
50 50
  ///\sa KaryHeap
51 51
#ifdef DOXYGEN
52 52
  template <typename PR, typename IM, typename CMP>
53 53
#else
54 54
  template <typename PR, typename IM, typename CMP = std::less<PR> >
55 55
#endif
56 56
  class FouraryHeap {
57 57
  public:
58 58
    /// Type of the item-int map.
59 59
    typedef IM ItemIntMap;
60 60
    /// Type of the priorities.
61 61
    typedef PR Prio;
62 62
    /// Type of the items stored in the heap.
63 63
    typedef typename ItemIntMap::Key Item;
64 64
    /// Type of the item-priority pairs.
65 65
    typedef std::pair<Item,Prio> Pair;
66 66
    /// Functor type for comparing the priorities.
67 67
    typedef CMP Compare;
68 68

	
69 69
    /// \brief Type to represent the states of the items.
70 70
    ///
71 71
    /// Each item has a state associated to it. It can be "in heap",
72 72
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
73 73
    /// heap's point of view, but may be useful to the user.
74 74
    ///
75 75
    /// The item-int map must be initialized in such way that it assigns
76 76
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
77 77
    enum State {
78 78
      IN_HEAP = 0,    ///< = 0.
79 79
      PRE_HEAP = -1,  ///< = -1.
80 80
      POST_HEAP = -2  ///< = -2.
81 81
    };
82 82

	
83 83
  private:
84 84
    std::vector<Pair> _data;
85 85
    Compare _comp;
86 86
    ItemIntMap &_iim;
87 87

	
88 88
  public:
89 89
    /// \brief Constructor.
90 90
    ///
91 91
    /// Constructor.
92 92
    /// \param map A map that assigns \c int values to the items.
93 93
    /// It is used internally to handle the cross references.
94 94
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
95 95
    explicit FouraryHeap(ItemIntMap &map) : _iim(map) {}
96 96

	
97 97
    /// \brief Constructor.
98 98
    ///
99 99
    /// Constructor.
100 100
    /// \param map A map that assigns \c int values to the items.
101 101
    /// It is used internally to handle the cross references.
102 102
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
103 103
    /// \param comp The function object used for comparing the priorities.
104 104
    FouraryHeap(ItemIntMap &map, const Compare &comp)
105 105
      : _iim(map), _comp(comp) {}
106 106

	
107 107
    /// \brief The number of items stored in the heap.
108 108
    ///
109 109
    /// This function returns the number of items stored in the heap.
110 110
    int size() const { return _data.size(); }
111 111

	
112 112
    /// \brief Check if the heap is empty.
113 113
    ///
114 114
    /// This function returns \c true if the heap is empty.
115 115
    bool empty() const { return _data.empty(); }
116 116

	
117 117
    /// \brief Make the heap empty.
118 118
    ///
119 119
    /// This functon makes the heap empty.
120 120
    /// It does not change the cross reference map. If you want to reuse
121 121
    /// a heap that is not surely empty, you should first clear it and
122 122
    /// then you should set the cross reference map to \c PRE_HEAP
123 123
    /// for each item.
124 124
    void clear() { _data.clear(); }
125 125

	
126 126
  private:
127 127
    static int parent(int i) { return (i-1)/4; }
128 128
    static int firstChild(int i) { return 4*i+1; }
129 129

	
130 130
    bool less(const Pair &p1, const Pair &p2) const {
131 131
      return _comp(p1.second, p2.second);
132 132
    }
133 133

	
134
    int findMin(const int child, const int length) {
135
      int min=child;
136
      if( child+3<length ) {
137
        if( less(_data[child+3], _data[min]) )
138
          min=child+3;
139
        if( less(_data[child+2], _data[min]) )
140
          min=child+2;
141
        if( less(_data[child+1], _data[min]) )
142
          min=child+1;
143
      }
144
      else if( child+2<length ) {
145
        if( less(_data[child+2], _data[min]) )
146
          min=child+2;
147
        if( less(_data[child+1], _data[min]) )
148
          min=child+1;
149
      }
150
      else if( child+1<length ) {
151
        if( less(_data[child+1], _data[min]) )
152
          min=child+1;
153
      }
154
      return min;
155
    }
156

	
157 134
    void bubbleUp(int hole, Pair p) {
158 135
      int par = parent(hole);
159 136
      while( hole>0 && less(p,_data[par]) ) {
160 137
        move(_data[par],hole);
161 138
        hole = par;
162 139
        par = parent(hole);
163 140
      }
164 141
      move(p, hole);
165 142
    }
166 143

	
167 144
    void bubbleDown(int hole, Pair p, int length) {
168 145
      if( length>1 ) {
169 146
        int child = firstChild(hole);
170
        while( child<length ) {
171
          child = findMin(child, length);
172
          if( !less(_data[child], p) )
147
        while( child+3<length ) {
148
          int min=child;
149
          if( less(_data[++child], _data[min]) ) min=child;
150
          if( less(_data[++child], _data[min]) ) min=child;
151
          if( less(_data[++child], _data[min]) ) min=child;
152
          if( !less(_data[min], p) )
173 153
            goto ok;
174
          move(_data[child], hole);
175
          hole = child;
154
          move(_data[min], hole);
155
          hole = min;
176 156
          child = firstChild(hole);
177 157
        }
158
        if ( child<length ) {
159
          int min = child;
160
          if( ++child<length && less(_data[child], _data[min]) ) min=child;
161
          if( ++child<length && less(_data[child], _data[min]) ) min=child;
162
          if( less(_data[min], p) ) {
163
            move(_data[min], hole);
164
            hole = min;
165
          }
166
        }
178 167
      }
179 168
    ok:
180 169
      move(p, hole);
181 170
    }
182 171

	
183 172
    void move(const Pair &p, int i) {
184 173
      _data[i] = p;
185 174
      _iim.set(p.first, i);
186 175
    }
187 176

	
188 177
  public:
189 178
    /// \brief Insert a pair of item and priority into the heap.
190 179
    ///
191 180
    /// This function inserts \c p.first to the heap with priority
192 181
    /// \c p.second.
193 182
    /// \param p The pair to insert.
194 183
    /// \pre \c p.first must not be stored in the heap.
195 184
    void push(const Pair &p) {
196 185
      int n = _data.size();
197 186
      _data.resize(n+1);
198 187
      bubbleUp(n, p);
199 188
    }
200 189

	
201 190
    /// \brief Insert an item into the heap with the given priority.
202 191
    ///
203 192
    /// This function inserts the given item into the heap with the
204 193
    /// given priority.
205 194
    /// \param i The item to insert.
206 195
    /// \param p The priority of the item.
207 196
    /// \pre \e i must not be stored in the heap.
208 197
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
209 198

	
210 199
    /// \brief Return the item having minimum priority.
211 200
    ///
212 201
    /// This function returns the item having minimum priority.
213 202
    /// \pre The heap must be non-empty.
214 203
    Item top() const { return _data[0].first; }
215 204

	
216 205
    /// \brief The minimum priority.
217 206
    ///
218 207
    /// This function returns the minimum priority.
219 208
    /// \pre The heap must be non-empty.
220 209
    Prio prio() const { return _data[0].second; }
221 210

	
222 211
    /// \brief Remove the item having minimum priority.
223 212
    ///
224 213
    /// This function removes the item having minimum priority.
225 214
    /// \pre The heap must be non-empty.
226 215
    void pop() {
227 216
      int n = _data.size()-1;
228 217
      _iim.set(_data[0].first, POST_HEAP);
229 218
      if (n>0) bubbleDown(0, _data[n], n);
230 219
      _data.pop_back();
231 220
    }
232 221

	
233 222
    /// \brief Remove the given item from the heap.
234 223
    ///
235 224
    /// This function removes the given item from the heap if it is
236 225
    /// already stored.
237 226
    /// \param i The item to delete.
238 227
    /// \pre \e i must be in the heap.
239 228
    void erase(const Item &i) {
240 229
      int h = _iim[i];
241 230
      int n = _data.size()-1;
242 231
      _iim.set(_data[h].first, POST_HEAP);
243 232
      if( h<n ) {
244 233
        if( less(_data[parent(h)], _data[n]) )
245 234
          bubbleDown(h, _data[n], n);
246 235
        else
247 236
          bubbleUp(h, _data[n]);
248 237
      }
249 238
      _data.pop_back();
250 239
    }
251 240

	
252 241
    /// \brief The priority of the given item.
253 242
    ///
254 243
    /// This function returns the priority of the given item.
255 244
    /// \param i The item.
256 245
    /// \pre \e i must be in the heap.
257 246
    Prio operator[](const Item &i) const {
258 247
      int idx = _iim[i];
259 248
      return _data[idx].second;
260 249
    }
261 250

	
262 251
    /// \brief Set the priority of an item or insert it, if it is
263 252
    /// not stored in the heap.
264 253
    ///
265 254
    /// This method sets the priority of the given item if it is
266 255
    /// already stored in the heap. Otherwise it inserts the given
267 256
    /// item into the heap with the given priority.
268 257
    /// \param i The item.
269 258
    /// \param p The priority.
270 259
    void set(const Item &i, const Prio &p) {
271 260
      int idx = _iim[i];
272 261
      if( idx < 0 )
273 262
        push(i,p);
274 263
      else if( _comp(p, _data[idx].second) )
275 264
        bubbleUp(idx, Pair(i,p));
276 265
      else
277 266
        bubbleDown(idx, Pair(i,p), _data.size());
278 267
    }
279 268

	
280 269
    /// \brief Decrease the priority of an item to the given value.
281 270
    ///
282 271
    /// This function decreases the priority of an item to the given value.
283 272
    /// \param i The item.
284 273
    /// \param p The priority.
285 274
    /// \pre \e i must be stored in the heap with priority at least \e p.
286 275
    void decrease(const Item &i, const Prio &p) {
287 276
      int idx = _iim[i];
288 277
      bubbleUp(idx, Pair(i,p));
289 278
    }
290 279

	
291 280
    /// \brief Increase the priority of an item to the given value.
292 281
    ///
293 282
    /// This function increases the priority of an item to the given value.
294 283
    /// \param i The item.
295 284
    /// \param p The priority.
296 285
    /// \pre \e i must be stored in the heap with priority at most \e p.
297 286
    void increase(const Item &i, const Prio &p) {
298 287
      int idx = _iim[i];
299 288
      bubbleDown(idx, Pair(i,p), _data.size());
300 289
    }
301 290

	
302 291
    /// \brief Return the state of an item.
303 292
    ///
304 293
    /// This method returns \c PRE_HEAP if the given item has never
305 294
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
306 295
    /// and \c POST_HEAP otherwise.
307 296
    /// In the latter case it is possible that the item will get back
308 297
    /// to the heap again.
309 298
    /// \param i The item.
310 299
    State state(const Item &i) const {
311 300
      int s = _iim[i];
312 301
      if (s>=0) s=0;
313 302
      return State(s);
314 303
    }
315 304

	
316 305
    /// \brief Set the state of an item in the heap.
317 306
    ///
318 307
    /// This function sets the state of the given item in the heap.
319 308
    /// It can be used to manually clear the heap when it is important
320 309
    /// to achive better time complexity.
321 310
    /// \param i The item.
322 311
    /// \param st The state. It should not be \c IN_HEAP.
323 312
    void state(const Item& i, State st) {
324 313
      switch (st) {
325 314
        case POST_HEAP:
326 315
        case PRE_HEAP:
327 316
          if (state(i) == IN_HEAP) erase(i);
328 317
          _iim[i] = st;
329 318
          break;
330 319
        case IN_HEAP:
331 320
          break;
332 321
      }
333 322
    }
334 323

	
335 324
    /// \brief Replace an item in the heap.
336 325
    ///
337 326
    /// This function replaces item \c i with item \c j.
338 327
    /// Item \c i must be in the heap, while \c j must be out of the heap.
339 328
    /// After calling this method, item \c i will be out of the
340 329
    /// heap and \c j will be in the heap with the same prioriority
341 330
    /// as item \c i had before.
342 331
    void replace(const Item& i, const Item& j) {
343 332
      int idx = _iim[i];
344 333
      _iim.set(i, _iim[j]);
345 334
      _iim.set(j, idx);
346 335
      _data[idx].first = j;
347 336
    }
348 337

	
349 338
  }; // class FouraryHeap
350 339

	
351 340
} // namespace lemon
352 341

	
353 342
#endif // LEMON_FOURARY_HEAP_H
Ignore white space 1024 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_KARY_HEAP_H
20 20
#define LEMON_KARY_HEAP_H
21 21

	
22 22
///\ingroup heaps
23 23
///\file
24 24
///\brief Fourary heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <utility>
28 28
#include <functional>
29 29

	
30 30
namespace lemon {
31 31

	
32 32
  /// \ingroup heaps
33 33
  ///
34 34
  ///\brief K-ary heap data structure.
35 35
  ///
36 36
  /// This class implements the \e K-ary \e heap data structure.
37 37
  /// It fully conforms to the \ref concepts::Heap "heap concept".
38 38
  ///
39 39
  /// The \ref KaryHeap "K-ary heap" is a generalization of the
40 40
  /// \ref BinHeap "binary heap" structure, its nodes have at most
41 41
  /// \c K children, instead of two.
42 42
  /// \ref BinHeap and \ref FouraryHeap are specialized implementations
43 43
  /// of this structure for <tt>K=2</tt> and <tt>K=4</tt>, respectively.
44 44
  ///
45 45
  /// \tparam PR Type of the priorities of the items.
46 46
  /// \tparam IM A read-writable item map with \c int values, used
47 47
  /// internally to handle the cross references.
48 48
  /// \tparam K The degree of the heap, each node have at most \e K
49 49
  /// children. The default is 16. Powers of two are suggested to use
50 50
  /// so that the multiplications and divisions needed to traverse the
51 51
  /// nodes of the heap could be performed faster.
52 52
  /// \tparam CMP A functor class for comparing the priorities.
53 53
  /// The default is \c std::less<PR>.
54 54
  ///
55 55
  ///\sa BinHeap
56 56
  ///\sa FouraryHeap
57 57
#ifdef DOXYGEN
58 58
  template <typename PR, typename IM, int K, typename CMP>
59 59
#else
60 60
  template <typename PR, typename IM, int K = 16,
61 61
            typename CMP = std::less<PR> >
62 62
#endif
63 63
  class KaryHeap {
64 64
  public:
65 65
    /// Type of the item-int map.
66 66
    typedef IM ItemIntMap;
67 67
    /// Type of the priorities.
68 68
    typedef PR Prio;
69 69
    /// Type of the items stored in the heap.
70 70
    typedef typename ItemIntMap::Key Item;
71 71
    /// Type of the item-priority pairs.
72 72
    typedef std::pair<Item,Prio> Pair;
73 73
    /// Functor type for comparing the priorities.
74 74
    typedef CMP Compare;
75 75

	
76 76
    /// \brief Type to represent the states of the items.
77 77
    ///
78 78
    /// Each item has a state associated to it. It can be "in heap",
79 79
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
80 80
    /// heap's point of view, but may be useful to the user.
81 81
    ///
82 82
    /// The item-int map must be initialized in such way that it assigns
83 83
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
84 84
    enum State {
85 85
      IN_HEAP = 0,    ///< = 0.
86 86
      PRE_HEAP = -1,  ///< = -1.
87 87
      POST_HEAP = -2  ///< = -2.
88 88
    };
89 89

	
90 90
  private:
91 91
    std::vector<Pair> _data;
92 92
    Compare _comp;
93 93
    ItemIntMap &_iim;
94 94

	
95 95
  public:
96 96
    /// \brief Constructor.
97 97
    ///
98 98
    /// Constructor.
99 99
    /// \param map A map that assigns \c int values to the items.
100 100
    /// It is used internally to handle the cross references.
101 101
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
102 102
    explicit KaryHeap(ItemIntMap &map) : _iim(map) {}
103 103

	
104 104
    /// \brief Constructor.
105 105
    ///
106 106
    /// Constructor.
107 107
    /// \param map A map that assigns \c int values to the items.
108 108
    /// It is used internally to handle the cross references.
109 109
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
110 110
    /// \param comp The function object used for comparing the priorities.
111 111
    KaryHeap(ItemIntMap &map, const Compare &comp)
112 112
      : _iim(map), _comp(comp) {}
113 113

	
114 114
    /// \brief The number of items stored in the heap.
115 115
    ///
116 116
    /// This function returns the number of items stored in the heap.
117 117
    int size() const { return _data.size(); }
118 118

	
119 119
    /// \brief Check if the heap is empty.
120 120
    ///
121 121
    /// This function returns \c true if the heap is empty.
122 122
    bool empty() const { return _data.empty(); }
123 123

	
124 124
    /// \brief Make the heap empty.
125 125
    ///
126 126
    /// This functon makes the heap empty.
127 127
    /// It does not change the cross reference map. If you want to reuse
128 128
    /// a heap that is not surely empty, you should first clear it and
129 129
    /// then you should set the cross reference map to \c PRE_HEAP
130 130
    /// for each item.
131 131
    void clear() { _data.clear(); }
132 132

	
133 133
  private:
134 134
    int parent(int i) { return (i-1)/K; }
135 135
    int firstChild(int i) { return K*i+1; }
136 136

	
137 137
    bool less(const Pair &p1, const Pair &p2) const {
138 138
      return _comp(p1.second, p2.second);
139 139
    }
140 140

	
141
    int findMin(const int child, const int length) {
142
      int min=child, i=1;
143
      while( i<K && child+i<length ) {
144
        if( less(_data[child+i], _data[min]) )
145
          min=child+i;
146
        ++i;
147
      }
148
      return min;
149
    }
150

	
151 141
    void bubbleUp(int hole, Pair p) {
152 142
      int par = parent(hole);
153 143
      while( hole>0 && less(p,_data[par]) ) {
154 144
        move(_data[par],hole);
155 145
        hole = par;
156 146
        par = parent(hole);
157 147
      }
158 148
      move(p, hole);
159 149
    }
160 150

	
161 151
    void bubbleDown(int hole, Pair p, int length) {
162 152
      if( length>1 ) {
163 153
        int child = firstChild(hole);
164
        while( child<length ) {
165
          child = findMin(child, length);
166
          if( !less(_data[child], p) )
154
        while( child+K<=length ) {
155
          int min=child;
156
          for (int i=1; i<K; ++i) {
157
            if( less(_data[child+i], _data[min]) )
158
              min=child+i;
159
          }
160
          if( !less(_data[min], p) )
167 161
            goto ok;
168
          move(_data[child], hole);
169
          hole = child;
162
          move(_data[min], hole);
163
          hole = min;
170 164
          child = firstChild(hole);
171 165
        }
166
        if ( child<length ) {
167
          int min = child;
168
          while (++child < length) {
169
            if( less(_data[child], _data[min]) )
170
              min=child;
171
          }
172
          if( less(_data[min], p) ) {
173
            move(_data[min], hole);
174
            hole = min;
175
          }
176
        }
172 177
      }
173 178
    ok:
174 179
      move(p, hole);
175 180
    }
176 181

	
177 182
    void move(const Pair &p, int i) {
178 183
      _data[i] = p;
179 184
      _iim.set(p.first, i);
180 185
    }
181 186

	
182 187
  public:
183 188
    /// \brief Insert a pair of item and priority into the heap.
184 189
    ///
185 190
    /// This function inserts \c p.first to the heap with priority
186 191
    /// \c p.second.
187 192
    /// \param p The pair to insert.
188 193
    /// \pre \c p.first must not be stored in the heap.
189 194
    void push(const Pair &p) {
190 195
      int n = _data.size();
191 196
      _data.resize(n+1);
192 197
      bubbleUp(n, p);
193 198
    }
194 199

	
195 200
    /// \brief Insert an item into the heap with the given priority.
196 201
    ///
197 202
    /// This function inserts the given item into the heap with the
198 203
    /// given priority.
199 204
    /// \param i The item to insert.
200 205
    /// \param p The priority of the item.
201 206
    /// \pre \e i must not be stored in the heap.
202 207
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
203 208

	
204 209
    /// \brief Return the item having minimum priority.
205 210
    ///
206 211
    /// This function returns the item having minimum priority.
207 212
    /// \pre The heap must be non-empty.
208 213
    Item top() const { return _data[0].first; }
209 214

	
210 215
    /// \brief The minimum priority.
211 216
    ///
212 217
    /// This function returns the minimum priority.
213 218
    /// \pre The heap must be non-empty.
214 219
    Prio prio() const { return _data[0].second; }
215 220

	
216 221
    /// \brief Remove the item having minimum priority.
217 222
    ///
218 223
    /// This function removes the item having minimum priority.
219 224
    /// \pre The heap must be non-empty.
220 225
    void pop() {
221 226
      int n = _data.size()-1;
222 227
      _iim.set(_data[0].first, POST_HEAP);
223 228
      if (n>0) bubbleDown(0, _data[n], n);
224 229
      _data.pop_back();
225 230
    }
226 231

	
227 232
    /// \brief Remove the given item from the heap.
228 233
    ///
229 234
    /// This function removes the given item from the heap if it is
230 235
    /// already stored.
231 236
    /// \param i The item to delete.
232 237
    /// \pre \e i must be in the heap.
233 238
    void erase(const Item &i) {
234 239
      int h = _iim[i];
235 240
      int n = _data.size()-1;
236 241
      _iim.set(_data[h].first, POST_HEAP);
237 242
      if( h<n ) {
238 243
        if( less(_data[parent(h)], _data[n]) )
239 244
          bubbleDown(h, _data[n], n);
240 245
        else
241 246
          bubbleUp(h, _data[n]);
242 247
      }
243 248
      _data.pop_back();
244 249
    }
245 250

	
246 251
    /// \brief The priority of the given item.
247 252
    ///
248 253
    /// This function returns the priority of the given item.
249 254
    /// \param i The item.
250 255
    /// \pre \e i must be in the heap.
251 256
    Prio operator[](const Item &i) const {
252 257
      int idx = _iim[i];
253 258
      return _data[idx].second;
254 259
    }
255 260

	
256 261
    /// \brief Set the priority of an item or insert it, if it is
257 262
    /// not stored in the heap.
258 263
    ///
259 264
    /// This method sets the priority of the given item if it is
260 265
    /// already stored in the heap. Otherwise it inserts the given
261 266
    /// item into the heap with the given priority.
262 267
    /// \param i The item.
263 268
    /// \param p The priority.
264 269
    void set(const Item &i, const Prio &p) {
265 270
      int idx = _iim[i];
266 271
      if( idx<0 )
267 272
        push(i,p);
268 273
      else if( _comp(p, _data[idx].second) )
269 274
        bubbleUp(idx, Pair(i,p));
270 275
      else
271 276
        bubbleDown(idx, Pair(i,p), _data.size());
272 277
    }
273 278

	
274 279
    /// \brief Decrease the priority of an item to the given value.
275 280
    ///
276 281
    /// This function decreases the priority of an item to the given value.
277 282
    /// \param i The item.
278 283
    /// \param p The priority.
279 284
    /// \pre \e i must be stored in the heap with priority at least \e p.
280 285
    void decrease(const Item &i, const Prio &p) {
281 286
      int idx = _iim[i];
282 287
      bubbleUp(idx, Pair(i,p));
283 288
    }
284 289

	
285 290
    /// \brief Increase the priority of an item to the given value.
286 291
    ///
287 292
    /// This function increases the priority of an item to the given value.
288 293
    /// \param i The item.
289 294
    /// \param p The priority.
290 295
    /// \pre \e i must be stored in the heap with priority at most \e p.
291 296
    void increase(const Item &i, const Prio &p) {
292 297
      int idx = _iim[i];
293 298
      bubbleDown(idx, Pair(i,p), _data.size());
294 299
    }
295 300

	
296 301
    /// \brief Return the state of an item.
297 302
    ///
298 303
    /// This method returns \c PRE_HEAP if the given item has never
299 304
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
300 305
    /// and \c POST_HEAP otherwise.
301 306
    /// In the latter case it is possible that the item will get back
302 307
    /// to the heap again.
303 308
    /// \param i The item.
304 309
    State state(const Item &i) const {
305 310
      int s = _iim[i];
306 311
      if (s>=0) s=0;
307 312
      return State(s);
308 313
    }
309 314

	
310 315
    /// \brief Set the state of an item in the heap.
311 316
    ///
312 317
    /// This function sets the state of the given item in the heap.
313 318
    /// It can be used to manually clear the heap when it is important
314 319
    /// to achive better time complexity.
315 320
    /// \param i The item.
316 321
    /// \param st The state. It should not be \c IN_HEAP.
317 322
    void state(const Item& i, State st) {
318 323
      switch (st) {
319 324
        case POST_HEAP:
320 325
        case PRE_HEAP:
321 326
          if (state(i) == IN_HEAP) erase(i);
322 327
          _iim[i] = st;
323 328
          break;
324 329
        case IN_HEAP:
325 330
          break;
326 331
      }
327 332
    }
328 333

	
329 334
    /// \brief Replace an item in the heap.
330 335
    ///
331 336
    /// This function replaces item \c i with item \c j.
332 337
    /// Item \c i must be in the heap, while \c j must be out of the heap.
333 338
    /// After calling this method, item \c i will be out of the
334 339
    /// heap and \c j will be in the heap with the same prioriority
335 340
    /// as item \c i had before.
336 341
    void replace(const Item& i, const Item& j) {
337 342
      int idx=_iim[i];
338 343
      _iim.set(i, _iim[j]);
339 344
      _iim.set(j, idx);
340 345
      _data[idx].first=j;
341 346
    }
342 347

	
343 348
  }; // class KaryHeap
344 349

	
345 350
} // namespace lemon
346 351

	
347 352
#endif // LEMON_KARY_HEAP_H
0 comments (0 inline)