Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
bin_heap.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file bin_heap.h
1 /* This software is distributed under the GNU Lesser General Public License */
2 //==========================================================================
3 //
4 // bin_heap.h
5 //
6 //==========================================================================
7 // $Id: bin_heap.h,v 1.10 2003/01/07 07:01:05 chris Exp $
8 
9 #ifndef GTL_BIN_HEAP_H
10 #define GTL_BIN_HEAP_H
11 
12 #include <GTL/GTL.h>
13 
14 #include <cassert>
15 #include <vector>
16 #include <map>
17 
19 
24 template <class T>
25 class heap_node
26 {
27 public:
33  {
34  }
35 
39  heap_node(const T& n) : data(n)
40  {
41  }
42 
48 
53  int pos;
54 };
55 
56 
62 template <class T, class Pred>
63 class bin_heap
64 {
65 public:
71  bin_heap(const Pred& prd);
72 
79  bin_heap(const Pred& prd, const int est_size);
80 
86  bin_heap(const bin_heap<T, Pred>& bh);
87 
99 
103  ~bin_heap();
104 
110  void push(const T& ins);
111 
115  void pop();
116 
122  const T& top() const;
123 
136  void changeKey(const T& cha);
137 
143  bool is_empty() const;
144 
149  void clear();
150 private:
155  const Pred& prd;
156 
161  int size;
162 
168  int capacity;
169 
174  vector<heap_node<T>* > container;
175 
180  map<T, heap_node<T>* > heap_node_map;
181 
186  void bubble_up(heap_node<T>* const n);
187 
192  void bubble_down(heap_node<T>* const n);
193 #ifdef _DEBUG
194 public:
199  void print_data_container();
200 #endif // _DEBUG
201 };
202 
203 // Implementation Begin
204 
205 template <class T, class Pred>
206 bin_heap<T, Pred>::bin_heap(const Pred& prd) :
207  prd(prd), size(0), capacity(50)
208 {
209  container.resize(capacity);
210 }
211 
212 
213 template <class T, class Pred>
214 bin_heap<T, Pred>::bin_heap(const Pred& prd, const int est_size) :
215  prd(prd), size(0), capacity(50)
216 {
217  if (est_size > 50)
218  {
219  capacity = est_size;
220  }
221  container.resize(capacity);
222 }
223 
224 
225 template <class T, class Pred>
227  prd(bh.prd), size(bh.size), capacity(bh.capacity)
228 {
229  container.resize(capacity);
230  for (int i = 0; i < size; ++i)
231  {
232  container[i] = new heap_node<T>(bh.container[i]->data);
233  }
234 }
235 
236 
237 template <class T, class Pred>
239 {
240  if (this != &bh) // no self assignment
241  {
242  assert(&prd == &(bh.prd));
243  clear();
244  size = bh.size;
245  capacity = bh.capacity;
246  container.resize(capacity);
247  for (int i = 0; i < size; ++i)
248  {
249  container[i] = new heap_node<T>(bh.container[i]->data);
250  }
251  }
252  return *this;
253 }
254 
255 
256 template <class T, class Pred>
258 {
259  clear();
260 }
261 
262 
263 template <class T, class Pred>
264 void bin_heap<T, Pred>::push(const T& ins)
265 {
266  if (size == capacity)
267  {
268  // dynamic memory allocation
269  capacity *= 2;
270  container.resize(capacity);
271  }
272  heap_node<T>* n = new heap_node<T>(ins);
273  n->pos = size;
274  container[size] = n;
275  heap_node_map[ins] = n;
276  ++size;
277  bubble_up(n);
278 }
279 
280 
281 template <class T, class Pred>
283 {
284  assert(size > 0);
285  // save smallest element for return (ensured by heap condition)
286  heap_node_map.erase(container[0]->data);
287  delete container[0];
288  // replace by last element in array and decrease heap "size"
289  if (size > 1)
290  {
291  container[0] = container[--size];
292  container[0]->pos = 0;
293  // reorder heap to ensure heap conditions
294  bubble_down(container[0]);
295  }
296  else
297  {
298  size = 0;
299  }
300 }
301 
302 
303 template <class T, class Pred>
304 const T& bin_heap<T, Pred>::top() const
305 {
306  return container[0]->data;
307 }
308 
309 
310 template <class T, class Pred>
312 {
313  int pos = heap_node_map[cha]->pos;
315  if (pos != 0)
316  {
317  heap_node<T>* father = container[(pos - 1) / 2];
318  if (prd(n->data, father->data))
319  {
320  bubble_up(n);
321  return;
322  }
323  }
324  bubble_down(n);
325 }
326 
327 
328 template <class T, class Pred>
330 {
331  // empty if if first free index is 0
332  return size == 0;
333 }
334 
335 
336 template <class T, class Pred>
338 {
339  for (int i = 0; i < size; ++i)
340  {
341  delete container[i];
342  }
343  size = 0;
344  heap_node_map.clear();
345 }
346 
347 
348 template <class T, class Pred>
350 {
351  int pos = n->pos;
352  // if we are not already at top AND the parent in heap is more
353  while ((pos != 0) &&
354  (prd(n->data, container[(pos - 1) / 2]->data)))
355  {
356  // move father down
357  container[pos] = container[(pos - 1) / 2];
358  container[pos]->pos = pos;
359  // increment k to parent index
360  pos = (pos - 1) / 2;
361  }
362  // place value in its highest position in heap
363  container[pos] = n;
364  container[pos]->pos = pos;
365 }
366 
367 
368 template <class T, class Pred>
370 {
371  int pos = n->pos;
372  int j = 0;
373  while (pos < size / 2)
374  {
375  j = 2 * pos + 1;
376  // if right child is smaller than left child get right child
377  if ((j < size - 1) &&
378  (prd(container[j + 1]->data, container[j]->data)))
379  {
380  ++j;
381  }
382  // if element is less or equal than its child leave it here
383  if (!prd(container[j]->data, n->data))
384  {
385  break;
386  }
387  // else move its child up
388  container[pos] = container[j];
389  container[pos]->pos = pos;
390  // repeat for new position
391  pos = j;
392  }
393  // place element into position, where heap condition is fulfilled
394  container[pos] = n;
395  container[pos]->pos = pos;
396 }
397 
398 #ifdef _DEBUG
399 template <class T, class Pred>
401 {
402  if (size == 0)
403  {
404  cout << "empty";
405  }
406  else
407  {
408  for (int pos = 0; pos < size; ++pos)
409  {
410  cout << container[pos]->data << " ";
411  }
412  }
413  cout << endl;
414 }
415 #endif // _DEBUG
416 
417 // Implementation End
418 
420 
421 #endif // GTL_BIN_HEAP_H
422 
423 //--------------------------------------------------------------------------
424 // end of file
425 //--------------------------------------------------------------------------