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_treap.H
1 
2 # ifndef TPL_TREAP_H
3 # define TPL_TREAP_H
4 
5 # include <gsl/gsl_rng.h>
6 # include <ahFunction.H>
7 # include <treapNode.H>
8 # include <tpl_binTreeOps.H>
9 
10 using namespace Aleph;
11 
12 namespace Aleph
13 {
14 
39  template <template <typename> class NodeType, typename Key, class Compare>
40 class Gen_Treap
41 {
42 public:
44  typedef NodeType<Key> Node;
45 
46 private:
47 
48  Node head;
49  Node * head_ptr;
50  Node *& tree_root;
51  gsl_rng * r;
52  Compare & cmp;
53 
54  void init(unsigned int seed)
55  {
56  PRIO(head_ptr) = Min_Priority;
57  r = gsl_rng_alloc (gsl_rng_mt19937);
58 
59  if (r == NULL)
60  throw std::bad_alloc();
61 
62  gsl_rng_set(r, seed % gsl_rng_max(r));
63  }
64 
65  public:
66 
72  void swap (Gen_Treap & tree)
73  {
74  std::swap(tree_root, tree.tree_root);
75  std::swap(cmp, tree.cmp);
76  std::swap(r, tree.r);
77  }
78 
80  Compare & key_comp() { return cmp; }
81 
83  Compare & get_compare() { return key_comp(); }
84 
86  Gen_Treap(unsigned int seed, Compare & __cmp)
87  : head_ptr(&head), tree_root(RLINK(head_ptr)), r(NULL), cmp(__cmp)
88  {
89  init(seed);
90  }
91 
92  Gen_Treap(unsigned int seed, Compare && __cmp)
93  : head_ptr(&head), tree_root(RLINK(head_ptr)), r(NULL), cmp(__cmp)
94  {
95  init(seed);
96  }
97 
100  {
101  if (r != NULL)
102  gsl_rng_free(r);
103  }
104 
106  gsl_rng * gsl_rng_object() { return r;}
107 
109  Node *& getRoot() { return tree_root; }
110 
112  Node * search(const Key & key)
113  {
114  Node* ret_val = searchInBinTree <Node, Compare> (tree_root, key, cmp);
115 
116  return ret_val == Node::NullPtr ? NULL : ret_val;
117  }
118 
119  private:
120 
121  Node * insert(Node * root, Node * p)
122  {
123  if (root == Node::NullPtr)
124  return p;
125 
126  Node * insertion_result = NULL;
127  if (cmp(KEY(p), KEY(root)))
128  {
129  insertion_result = insert(LLINK(root), p);
130  if (insertion_result == Node::NullPtr)
131  return Node::NullPtr;
132 
133  LLINK(root) = insertion_result;
134  if (PRIO(insertion_result) < PRIO(root))
135  return rotate_to_right(root);
136  else
137  return root;
138  }
139  else if (cmp(KEY(root), KEY(p)))
140  {
141  insertion_result = insert(RLINK(root), p);
142  if (insertion_result == Node::NullPtr)
143  return Node::NullPtr;
144 
145  RLINK(root) = insertion_result;
146  if (PRIO(insertion_result) < PRIO(root))
147  return rotate_to_left(root);
148  else
149  return root;
150  }
151 
152  return Node::NullPtr;
153  }
154 
155  // busca o inserta p. Retorna p si KEY(p) no se encuentra dentro del
156  // árbol; de lo contrario, se retorna la dirección del nodo contentivo
157  // de KEY(p)
158  Node * search_or_insert (Node *& root, Node * p)
159  {
160  if (root == Node::NullPtr)
161  return root = p;
162 
163  if (cmp(KEY(p), KEY(root)))
164  {
165  Node * ret = search_or_insert(LLINK(root), p);
166  if (ret == p) // ¿hubo inserción?
167  // sí la hubo ==> eventualmente reequilibrar
168  if (PRIO(LLINK(root)) < PRIO(root))
169  root = rotate_to_right (root);
170 
171  return ret;
172  }
173  else if (cmp(KEY(root), KEY(p)))
174  {
175  Node * ret = search_or_insert(RLINK(root), p);
176  if (ret == p) // ¿hubo inserción?
177  // sí la hubo ==> eventualmente reequilibrar
178  if (PRIO(RLINK(root)) < PRIO(root))
179  root = rotate_to_left (root);
180 
181  return ret;
182  }
183 
184  return root; // root contiene KEY(p)
185  }
186 
187  Node * insert_dup(Node * root, Node * p)
188  {
189  if (root == Node::NullPtr)
190  return p;
191 
192  if (cmp(KEY(p), KEY(root)))
193  {
194  Node * result = LLINK(root) = insert_dup(LLINK(root), p);
195  if (PRIO(result) < PRIO(root))
196  return rotate_to_right(root);
197  else
198  return root;
199  }
200 
201  Node * result = RLINK(root) = insert_dup(RLINK(root), p);
202 
203  if (PRIO(result) < PRIO(root))
204  return rotate_to_left(root);
205  else
206  return root;
207  }
208 
209  public:
210 
219  Node * insert(Node * p)
220  {
221  I(p != Node::NullPtr);
222 
223  PRIO(p) = gsl_rng_get(r); // selección aleatoria de prioridad
224  Node * result = insert(tree_root, p);
225  if (result == Node::NullPtr)
226  return NULL;
227 
228  tree_root = result;
229 
230  return p;
231  }
232 
248  {
249  I(p != Node::NullPtr);
250 
251  PRIO(p) = gsl_rng_get(r); // selección aleatoria de prioridad
252 
253  return search_or_insert(tree_root, p);
254  }
255 
265  {
266  I(p != Node::NullPtr);
267 
268  PRIO(p) = gsl_rng_get(r); // selección aleatoria de prioridad
269  tree_root = insert_dup(tree_root, p);
270 
271  return p;
272  }
273 
274  bool verify() { return is_treap(tree_root); }
275 
285  Node * remove(const Key & key)
286  {
287  Node ** pp = &RLINK(head_ptr);
288  Node * p = tree_root;
289 
290  // descender buscando la clave
291  while (p != Node::NullPtr)
292  if (cmp(key, KEY(p)))
293  {
294  pp = &LLINK(p);
295  p = LLINK(p);
296  }
297  else if (cmp(KEY(p), key))
298  {
299  pp = &RLINK(p);
300  p = RLINK(p);
301  }
302  else
303  break; // encontrada!
304 
305  if (p == Node::NullPtr)
306  return NULL; // clave no fue encontrada
307 
308  // rotar p hasta que devenga hoja
309  while (not (LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr))
310  if (PRIO(LLINK(p)) < PRIO(RLINK(p)))
311  {
312  *pp = rotate_to_right(p);
313  pp = &RLINK(*pp);
314  }
315  else
316  {
317  *pp = rotate_to_left(p);
318  pp = &LLINK(*pp);
319  }
320 
321  *pp = Node::NullPtr;
322 
323  p->reset();
324 
325  return p;
326  }
327 };
328 
351  template <typename Key, class Compare = Aleph::less<Key>>
352 class Treap : public Gen_Treap<TreapNode, Key, Compare>
353 {
354 public:
355 
356  Treap(unsigned int seed, Compare && cmp = Compare())
357  : Gen_Treap<TreapNode, Key, Compare>(seed, std::move(cmp))
358  {
359  // empty
360  }
361 
362  Treap(Compare && cmp = Compare())
363  : Gen_Treap<TreapNode, Key, Compare>(time(NULL), std::move(cmp))
364  {
365  // empty
366  }
367 
368  Treap(unsigned int seed, Compare & cmp)
370  {
371  // empty
372  }
373 
374  Treap(Compare & cmp)
375  : Gen_Treap<TreapNode, Key, Compare>(time(NULL), cmp)
376  {
377  // empty
378  }
379 };
380 
403  template <typename Key, class Compare = Aleph::less<Key>>
404 class Treap_Vtl : public Gen_Treap<TreapNodeVtl, Key, Compare>
405 {
406 public:
407 
408  Treap_Vtl(unsigned int seed, Compare && cmp = Compare())
409  : Gen_Treap<TreapNodeVtl, Key, Compare>(seed, std::move(cmp))
410  {
411  // empty
412  }
413 
414  Treap_Vtl(Compare && cmp = Compare())
415  : Gen_Treap<TreapNodeVtl, Key, Compare>(time(NULL), std::move(cmp))
416  {
417  // empty
418  }
419 
420  Treap_Vtl(unsigned int seed, Compare & cmp)
422  {
423  // empty
424  }
425 
426  Treap_Vtl(Compare & cmp)
427  : Gen_Treap<TreapNodeVtl, Key, Compare>(time(NULL), cmp)
428  {
429  // empty
430  }
431 };
432 
433 
434 } // end namespace Aleph
435 # endif // TPL_TREAP_H
436 
Node * rotate_to_left(Node *p)
Definition: tpl_binNodeUtils.H:2422
#define LLINK(p)
Definition: tpl_binNode.H:196
#define RLINK(p)
Definition: tpl_binNode.H:201
Node *& getRoot()
Retorna la raíz del treap.
Definition: tpl_treap.H:109
Node * search_or_insert(Node *p)
Definition: tpl_treap.H:247
Definition: tpl_treap.H:404
Definition: tpl_treap.H:352
NodeType< Key > Node
Tipo de nodo del treap.
Definition: tpl_treap.H:44
Node * rotate_to_right(Node *p)
Definition: tpl_binNodeUtils.H:2375
Compare & get_compare()
Definition: tpl_treap.H:83
~Gen_Treap()
Destructor; libera memoria de generador de números aleatorios.
Definition: tpl_treap.H:99
Node * insert_dup(Node *p)
Definition: tpl_treap.H:264
gsl_rng * gsl_rng_object()
Obtiene un puntero al objeto gsl_rng generador de números aleatorios.
Definition: tpl_treap.H:106
Gen_Treap(unsigned int seed, Compare &__cmp)
Constructor; inicializa generador de números aleatorios.
Definition: tpl_treap.H:86
Node * search(const Key &key)
Busca la clave key en el treap.
Definition: tpl_treap.H:112
Definition: tpl_treap.H:40
Compare & key_comp()
Retorna una referencia al criterio de comparación.
Definition: tpl_treap.H:80
Node * insert(Node *p)
Definition: tpl_treap.H:219
#define KEY(p)
Definition: tpl_binNode.H:206
void swap(Gen_Treap &tree)
Definition: tpl_treap.H:72

Leandro Rabindranath León