OpenMesh
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
HeapT.hh
Go to the documentation of this file.
1 /*===========================================================================*\
2  * *
3  * OpenMesh *
4  * Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen *
5  * www.openmesh.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenMesh. *
9  * *
10  * OpenMesh is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or (at your option) any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenMesh is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenMesh. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36  * *
37  * $Revision: 736 $ *
38  * $Date: 2012-10-08 09:30:49 +0200 (Mo, 08 Okt 2012) $ *
39  * *
40 \*===========================================================================*/
41 
60 //=============================================================================
61 //
62 // CLASS HeapT
63 //
64 //=============================================================================
65 
66 #ifndef OPENMESH_UTILS_HEAPT_HH
67 #define OPENMESH_UTILS_HEAPT_HH
68 
69 
70 //== INCLUDES =================================================================
71 
72 #include "Config.hh"
73 #include <vector>
75 
76 //== NAMESPACE ================================================================
77 
78 namespace OpenMesh { // BEGIN_NS_OPENMESH
79 namespace Utils { // BEGIN_NS_UTILS
80 
81 //== CLASS DEFINITION =========================================================
82 
83 
92 template <class HeapEntry>
94 {
96  bool less(const HeapEntry& _e1, const HeapEntry& _e2);
97 
99  bool greater(const HeapEntry& _e1, const HeapEntry& _e2);
100 
102  int get_heap_position(const HeapEntry& _e);
103 
105  void set_heap_position(HeapEntry& _e, int _i);
106 };
107 
108 
109 
132 template <class HeapEntry, class HeapInterface=HeapEntry>
133 class HeapT : private std::vector<HeapEntry>
134 {
135 private:
136  typedef std::vector<HeapEntry> Base;
137 
138 public:
139 
141  HeapT() : HeapVector() {}
142 
144  HeapT(const HeapInterface& _interface)
145  : HeapVector(), interface_(_interface)
146  {}
147 
149  ~HeapT(){};
150 
151 
153  void clear() { HeapVector::clear(); }
154 
156  bool empty() const { return HeapVector::empty(); }
157 
159  unsigned int size() const { return HeapVector::size(); }
160 
162  void reserve(unsigned int _n) { HeapVector::reserve(_n); }
163 
165  void reset_heap_position(HeapEntry _h)
166  { interface_.set_heap_position(_h, -1); }
167 
169  bool is_stored(HeapEntry _h)
170  { return interface_.get_heap_position(_h) != -1; }
171 
173  void insert(HeapEntry _h)
174  {
175  this->push_back(_h);
176  upheap(size()-1);
177  }
178 
180  HeapEntry front() const
181  {
182  assert(!empty());
183  return entry(0);
184  }
185 
187  void pop_front()
188  {
189  assert(!empty());
190  reset_heap_position(entry(0));
191  if (size() > 1)
192  {
193  entry(0, entry(size()-1));
194  Base::pop_back();
195  downheap(0);
196  }
197  else
198  {
199  Base::pop_back();
200  }
201  }
202 
204  void remove(HeapEntry _h)
205  {
206  int pos = interface_.get_heap_position(_h);
208 
209  assert(pos != -1);
210  assert((unsigned int) pos < size());
211 
212  // last item ?
213  if ((unsigned int) pos == size()-1)
214  {
215  Base::pop_back();
216  }
217  else
218  {
219  entry(pos, entry(size()-1)); // move last elem to pos
220  Base::pop_back();
221  downheap(pos);
222  upheap(pos);
223  }
224  }
225 
229  void update(HeapEntry _h)
230  {
231  int pos = interface_.get_heap_position(_h);
232  assert(pos != -1);
233  assert((unsigned int)pos < size());
234  downheap(pos);
235  upheap(pos);
236  }
237 
239  bool check()
240  {
241  bool ok(true);
242  unsigned int i, j;
243  for (i=0; i<size(); ++i)
244  {
245  if (((j=left(i))<size()) && interface_.greater(entry(i), entry(j)))
246  {
247  omerr() << "Heap condition violated\n";
248  ok=false;
249  }
250  if (((j=right(i))<size()) && interface_.greater(entry(i), entry(j)))
251  {
252  omerr() << "Heap condition violated\n";
253  ok=false;
254  }
255  }
256  return ok;
257  }
258 
259 protected:
261  HeapInterface interface_;
262 
263 private:
264  // typedef
265  typedef std::vector<HeapEntry> HeapVector;
266 
267 
269  void upheap(unsigned int _idx);
270 
271 
273  void downheap(unsigned int _idx);
274 
275 
277  inline HeapEntry entry(unsigned int _idx) const
278  {
279  assert(_idx < size());
280  return (Base::operator[](_idx));
281  }
282 
283 
285  inline void entry(unsigned int _idx, HeapEntry _h)
286  {
287  assert(_idx < size());
288  Base::operator[](_idx) = _h;
289  interface_.set_heap_position(_h, _idx);
290  }
291 
292 
294  inline unsigned int parent(unsigned int _i) { return (_i-1)>>1; }
296  inline unsigned int left(unsigned int _i) { return (_i<<1)+1; }
298  inline unsigned int right(unsigned int _i) { return (_i<<1)+2; }
299 
300 };
301 
302 
303 
304 
305 //== IMPLEMENTATION ==========================================================
306 
307 
308 template <class HeapEntry, class HeapInterface>
309 void
310 HeapT<HeapEntry, HeapInterface>::
311 upheap(unsigned int _idx)
312 {
313  HeapEntry h = entry(_idx);
314  unsigned int parentIdx;
315 
316  while ((_idx>0) &&
317  interface_.less(h, entry(parentIdx=parent(_idx))))
318  {
319  entry(_idx, entry(parentIdx));
320  _idx = parentIdx;
321  }
322 
323  entry(_idx, h);
324 }
325 
326 
327 //-----------------------------------------------------------------------------
328 
329 
330 template <class HeapEntry, class HeapInterface>
331 void
332 HeapT<HeapEntry, HeapInterface>::
333 downheap(unsigned int _idx)
334 {
335  HeapEntry h = entry(_idx);
336  unsigned int childIdx;
337  unsigned int s = size();
338 
339  while(_idx < s)
340  {
341  childIdx = left(_idx);
342  if (childIdx >= s) break;
343 
344  if ((childIdx + 1 < s) && (interface_.less(entry(childIdx + 1), entry(childIdx))))
345  ++childIdx;
346 
347  if (interface_.less(h, entry(childIdx))) break;
348 
349  entry(_idx, entry(childIdx));
350  _idx = childIdx;
351  }
352 
353  entry(_idx, h);
354 }
355 
356 
357 //=============================================================================
358 } // END_NS_UTILS
359 } // END_NS_OPENMESH
360 //=============================================================================
361 #endif // OSG_HEAP_HH defined
362 //=============================================================================
363 

acg pic Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .