Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
tpl_arrayHeap.H
1 
2 # ifndef TPL_ARRAYHEAP_H
3 # define TPL_ARRAYHEAP_H
4 
5 # include <ahFunction.H>
6 # include <ahUtils.H>
7 # include <ahDefs.H>
8 # include <ahAssert.H>
9 # include <ahDry.H>
10 
11 namespace Aleph {
12 
13 
14  template <typename T, class Compare> inline
15 T & sift_up(T * ptr, const size_t l, const size_t r)
16 {
17  size_t i = r;
18  for (size_t p; i > l; i = p)
19  {
20  p = u_index(i); // índice del padre (c = i/2)
21  if (Compare () (ptr[p], ptr[i])) // ¿cumple propiedad orden?
22  return ptr[i]; // si, todo el arreglo es un heap
23 
24  std::swap(ptr[p], ptr[i]); // intercambie y restaure nivel p
25  }
26 
27  return ptr[i];
28 }
29 
30  template <typename T, class Compare> inline
31 void sift_down(T * ptr, const size_t l, const size_t r)
32 {
33  size_t i = l, c;
34  while (true)
35  {
36  c = l_index(i); // índice del hijo izquierdo (c = i/2)
37  if (c > r) // ¿hay hijo izquierdo?
38  return; // no ==> termine
39 
40  if (c + 1 <= r) // ¿hay hijo derecho?
41  if (Compare () (ptr[c + 1], ptr[c])) // sí ==> escoja menor
42  c++;
43 
44  if (Compare () (ptr[i], ptr[c])) // ¿cumple propiedad orden?
45  return; // sí ==> termine
46 
47  std::swap(ptr[c], ptr[i]);
48  i = c;
49  }
50 }
51 
52  template <typename T, class Compare> inline
53 void sift_down_up(T * ptr, const size_t l, const size_t i, const size_t r)
54 {
55  sift_down <T, Compare> (ptr, i, r);
56  sift_up <T, Compare> (ptr, l, i);
57 }
58 
80  template <typename T, class Compare = Aleph::less<T> >
81 void heapsort(T * array, const size_t n)
82 {
83  --array; //desplazar posición hacia atrás ==> array[1] == primero
84  for (int i = 2; i <= n; ++i)
85  sift_up <T, Aleph::Inversed_Compare<T, Compare> > (array, 1, i);
86  for (int i = n; i > 1; --i)
87  {
88  std::swap(array[1], array[i]); // poner en raíz i-ésimo item
89  sift_down<T,Aleph::Inversed_Compare<T,Compare> >(array, 1, i - 1);
90  }
91 }
92 
114  template <typename T, class Compare = Aleph::less<T> >
115 void faster_heapsort(T * array, const size_t n)
116 {
117  --array; // desplazar posición hacia atrás ==> array[1] == primero
118  for (int i = n/2; i >= 1; --i)
119  sift_down <T, Aleph::Inversed_Compare<T, Compare> > (array, i, n);
120  for (int i = n; i > 1; --i)
121  {
122  std::swap(array[1], array[i]); // poner en raíz i-ésimo item
123  sift_down<T,Aleph::Inversed_Compare<T,Compare> >(array, 1, i - 1);
124  }
125 }
126 
129  template <typename T, class Compare>
130 bool valid_heap(T * array, const size_t l, const size_t r)
131 {
132  size_t i;
133  for (i = l_index(l) /* i = 2*l */; i <= r; i++)
134  if (Compare () (array[i], array[u_index (i)]))
135  break;
136  return i > r;
137 }
138 
152  template <typename T, class Compare = Aleph::less<T>>
153 class ArrayHeap
154 {
155  T * array;
156  const size_t dim;
157  size_t num_items;
158 
159  static size_t r_index(const size_t & i)
160  {
161  return (i << 1) + 1; // multiplica i por 2 y suma 1
162  }
163 
164  mutable bool array_allocated;
165 
166 public:
167 
169  ArrayHeap(const size_t & d = 1024)
170  : array(NULL), dim(d), num_items(0), array_allocated(false)
171  {
172  array = new T [d + 1];
173  array_allocated = true;
174  }
175 
177  ArrayHeap(T * ptr, const size_t & d)
178  : array(ptr), dim(d), num_items(0), array_allocated(false)
179  {
180  // empty
181  }
182 
184  virtual ~ArrayHeap()
185  {
186  if (array_allocated and array != NULL)
187  delete [] array;
188  }
189 
191  T & top() throw(std::exception, std::underflow_error)
192  {
193  if (num_items == 0)
194  throw std::underflow_error("Heap is empty");
195 
196  return array[1];
197  }
198 
208  T & insert(const T & key) throw(std::exception, std::overflow_error)
209  {
210  if (num_items >= dim)
211  throw std::overflow_error("Heap out of capacity");
212 
213  array[++num_items] = key; // colocar nuevo elemento
214  return sift_up<T,Compare>(array, 1, num_items);
215  }
216 
226  T getMin() throw(std::exception, std::underflow_error)
227  {
228  if (num_items == 0)
229  throw std::underflow_error("Heap is empty");
230 
231  T ret_val = array[1];
232  array[1] = array[num_items--];
233  sift_down<T, Compare>(array, 1, num_items);
234  return ret_val;
235  }
236 
238  T get() throw(std::exception, std::underflow_error)
239  {
240  return getMin();
241  }
242 
244  T getMax() throw(std::exception, std::underflow_error)
245  {
246  return getMin();
247  }
248 
250  const size_t & size() const { return num_items; }
251 
253  bool is_empty() const { return num_items == 0; }
254 
272  void update(T & data)
273  {
274  I(&data >= &array[0] and &data <= &array[dim]);
275 
276  const size_t i = &data - array;
277  sift_down_up <T, Compare> (array, 1, i, num_items);
278  sift_up <T, Compare> (array, i, num_items);
279  }
280 
281  void remove(T & item)
282  {
283  item = array[num_items--];
284  update(item);
285  }
286 
288  T & operator [] (const size_t i)
289  {
290  return array[i];
291  }
292 
293 private:
294 
295  // super fast array traversal
296  template <class Operation>
297  bool __traverse(Operation & operation)
298  {
299  for (size_t i = 1; i <= num_items; ++i)
300  if (not operation(array[i]))
301  return false;
302 
303  return true;
304  }
305 
306 public:
307 
308  template <class Operation>
309  bool traverse(Operation & operation) const
310  {
311  return const_cast<ArrayHeap&>(*this).__traverse(operation);
312  }
313 
314  template <class Operation>
315  bool traverse(Operation & operation)
316  {
317  return __traverse(operation);
318  }
319 
320  template <class Operation>
321  bool traverse(Operation && operation = Operation()) const
322  {
323  return const_cast<ArrayHeap&>(*this).__traverse(operation);
324  }
325 
326  template <class Operation>
327  bool traverse(Operation && operation = Operation())
328  {
329  return traverse(operation);
330  }
331 
332  Functional_Methods(T);
333 };
334 
335 } // end namespace Aleph
336 # endif /* TPL_ARRAYHEAP_H */
337 
void update(T &data)
Definition: tpl_arrayHeap.H:272
T getMax()
Definition: tpl_arrayHeap.H:244
Definition: ahFunction.H:942
Definition: tpl_arrayHeap.H:153
T getMin()
Definition: tpl_arrayHeap.H:226
virtual ~ArrayHeap()
Destructor.
Definition: tpl_arrayHeap.H:184
void heapsort(T *array, const size_t n)
Definition: tpl_arrayHeap.H:81
const size_t & size() const
Retorna la cantidad de elementos.
Definition: tpl_arrayHeap.H:250
void faster_heapsort(T *array, const size_t n)
Definition: tpl_arrayHeap.H:115
T & operator[](const size_t i)
Retorna la i-ésima entrada del heap.
Definition: tpl_arrayHeap.H:288
ArrayHeap(T *ptr, const size_t &d)
Constructor con arreglo y dimensión.
Definition: tpl_arrayHeap.H:177
T & top()
Retorna el menor elemento del heap.
Definition: tpl_arrayHeap.H:191
T & insert(const T &key)
Definition: tpl_arrayHeap.H:208
bool is_empty() const
Retorna true si el heap está vacío.
Definition: tpl_arrayHeap.H:253
ArrayHeap(const size_t &d=1024)
Constructor con dimensión por omisión.
Definition: tpl_arrayHeap.H:169

Leandro Rabindranath León