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_treapRk.H
1 # ifndef TPL_TREAPRK_H
2 # define TPL_TREAPRK_H
3 
4 # include <gsl/gsl_rng.h>
5 # include <ahFunction.H>
6 # include <tpl_binTreeOps.H>
7 # include <ran_array.h>
8 # include <treapNode.H>
9 
10 using namespace Aleph;
11 
12 namespace Aleph {
13 
15 {
16  unsigned long priority;
17 
18  unsigned long count;
19 
20 public:
21 
22  TreapRkNode_Data() : priority(Max_Priority), count(1)
23  {
24  /* empty */
25  }
26 
27  TreapRkNode_Data(SentinelCtor)
28  : priority(Max_Priority), count(0)
29  {
30  /* empty */
31  }
32 
33  unsigned long & getPriority() { return priority; }
34 
35  unsigned long & getCount() { return count; }
36 
37  void reset()
38  {
39  priority = Max_Priority;
40  count = 1;
41  }
42 };
43 
44 DECLARE_BINNODE_SENTINEL(Treap_Rk_Node, 80, TreapRkNode_Data);
45 
46 
86  template <template <class> class NodeType, class Key, class Compare>
88 {
89 public:
90 
92  typedef NodeType<Key> Node;
93 
94 private:
95 
96  Node head;
97  Node * head_ptr;
98  Node *& tree_root;
99  gsl_rng * r;
100  Compare & cmp;
101 
102  void init(unsigned int seed)
103  {
104  PRIO(head_ptr) = Min_Priority;
105  r = gsl_rng_alloc(gsl_rng_mt19937);
106 
107  if (r == NULL)
108  throw std::bad_alloc();
109 
110  gsl_rng_set(r, seed % gsl_rng_max(r));
111  }
112 
113 public:
114 
116  Compare & key_comp() { return cmp; }
117 
119  Compare & get_compare() { return key_comp(); }
120 
122  Gen_Treap_Rk(unsigned int seed, Compare & __cmp)
123  : head_ptr(&head), tree_root(RLINK(head_ptr)), r(NULL), cmp(__cmp)
124  {
125  init(seed);
126  }
127 
128  Gen_Treap_Rk(unsigned int seed, Compare && __cmp)
129  : head_ptr(&head), tree_root(RLINK(head_ptr)), r(NULL), cmp(__cmp)
130  {
131  init(seed);
132  }
133 
134  ~Gen_Treap_Rk()
135  {
136  if (r != NULL)
137  gsl_rng_free(r);
138  }
139 
146  {
147  // empty
148  }
149 
155  void swap(Gen_Treap_Rk & tree)
156  {
157  std::swap(tree_root, tree.tree_root);
158  std::swap(cmp, tree.cmp);
159  std::swap(r, tree.r);
160  }
161 
163  Node *& getRoot() { return tree_root; }
164 
166  Node * search(const Key & key)
167  {
168  Node* ret_val = searchInBinTree<Node, Compare>(tree_root, key, cmp);
169 
170  return ret_val == Node::NullPtr ? NULL : ret_val;
171  }
172 
173 private:
174 
175  // retorna true si la clave fue insertada (si no se encuentra en el árbol)
176  bool insert(Node *& root, Node * p)
177  {
178  if (root == Node::NullPtr)
179  {
180  root = p;
181  return true;
182  }
183 
184  if (cmp(KEY(p), KEY(root)))
185  {
186  if (insert(LLINK(root), p))
187  {
188  ++COUNT(root);
189  if (PRIO(LLINK(root)) < PRIO(root) )
190  root = rotate_to_right_xt(root);
191 
192  return true;
193  }
194  }
195  else if (cmp(KEY(root), KEY(p)))
196  {
197  if (insert(RLINK(root), p))
198  {
199  ++COUNT(root);
200  if (PRIO(RLINK(root)) < PRIO(root) )
201  root = rotate_to_left_xt(root);
202 
203  return true;
204  }
205  }
206 
207  return false;
208  }
209 
210 public:
211 
212  // busca o inserta p. Retorna p si KEY(p) no se encuentra dentro del
213  // árbol; de lo contrario, se retorna la dirección del nodo contentivo
214  // de KEY(p)
215  Node * search_or_insert(Node *& root, Node * p)
216  {
217  if (root == Node::NullPtr)
218  return root = p;
219 
220  if (cmp(KEY(p), KEY(root)))
221  {
222  Node * ret = search_or_insert(LLINK(root), p);
223  if (ret == p) // ¿hubo inserción?
224  { // sí la hubo ==> incrementar contadores y eventualmente
225  // reequilibrar
226  ++COUNT(root);
227  if (PRIO(LLINK(root)) < PRIO(root))
228  root = rotate_to_right_xt(root);
229 
230  I(PRIO(root) <= PRIO(LLINK(root)) and
231  PRIO(root) <= PRIO(LLINK(root)));
232  }
233 
234  return ret;
235  }
236  else if (cmp(KEY(root), KEY(p)))
237  {
238  Node * ret = search_or_insert(RLINK(root), p);
239  if (ret == p) // ¿hubo inserción?
240  { // sí la hubo ==> incrementar contadores y eventualmente
241  // reequilibrar
242  ++COUNT(root);
243  if (PRIO(RLINK(root)) < PRIO(root))
244  root = rotate_to_left_xt(root);
245 
246  I(PRIO(root) <= PRIO(LLINK(root)) and
247  PRIO(root) <= PRIO(LLINK(root)));
248  }
249 
250  return ret;
251  }
252 
253  I(PRIO(root) <= PRIO(LLINK(root)) and PRIO(root) <= PRIO(LLINK(root)));
254 
255  return root; // root contiene KEY(p)
256  }
257 
258  // retorna p
259  Node * insert_dup(Node *& root, Node * p)
260  {
261  if (root == Node::NullPtr)
262  return root = p;
263 
264  if (cmp(KEY(p), KEY(root)))
265  {
266  insert_dup(LLINK(root), p);
267  ++COUNT(root);
268  if (PRIO(LLINK(root)) < PRIO(root))
269  root = rotate_to_right_xt(root);
270  }
271  else
272  {
273  insert_dup(RLINK(root), p);
274  ++COUNT(root);
275  if (PRIO(RLINK(root)) < PRIO(root))
276  root = rotate_to_left_xt(root);
277  }
278 
279  return p;
280  }
281 
290  Node * insert(Node * p)
291  {
292  I (p != Node::NullPtr);
293 
294  PRIO(p) = gsl_rng_get(r);
295 
296  return insert(tree_root, p) ? p : NULL;
297  }
298 
299 
309  {
310  I(p != Node::NullPtr);
311 
312  PRIO(p) = gsl_rng_get(r);
313 
314  return insert_dup(tree_root, p);
315  }
316 
330  {
331  I(p != Node::NullPtr);
332 
333  PRIO(p) = gsl_rng_get(r);
334 
335  return search_or_insert(tree_root, p);
336  }
337 
338  bool verify() { return is_treap(tree_root); }
339 
340 private:
341 
342  static Node * join_treaps(Node * t1, Node * t2)
343  {
344  if (t1 == Node::NullPtr)
345  return t2;
346 
347  if (t2 == Node::NullPtr)
348  return t1;
349 
350  if (PRIO(t1) < PRIO(t2) )
351  {
352  COUNT(t1) += COUNT(t2);
353  RLINK(t1) = join_treaps(RLINK(t1), t2);
354 
355  return t1;
356  }
357  else
358  {
359  COUNT(t2) += COUNT(t1);
360  LLINK(t2) = join_treaps(t1, LLINK(t2) );
361 
362  return t2;
363  }
364  }
365 
366  Node * remove(Node *& root, const Key & key)
367  {
368  if (root == Node::NullPtr)
369  return Node::NullPtr;
370 
371  Node * ret_val;
372 
373  if (cmp(key, KEY(root) ))
374  ret_val = remove(LLINK(root), key);
375  else if (cmp(KEY(root), key))
376  ret_val = remove(RLINK(root), key);
377  else
378  {
379  ret_val = root;
380  root = join_treaps(LLINK(root), RLINK(root) );
381 
382  return ret_val;
383  }
384 
385  if (ret_val == Node::NullPtr)
386  return Node::NullPtr;
387 
388  --COUNT(root);
389 
390  return ret_val;
391  }
392 
393 public:
394 
404  Node * remove(const Key & key)
405  {
406  Node * ret_val = remove(tree_root, key);
407 
408  if (ret_val == Node::NullPtr)
409  return NULL;
410 
411  ret_val->reset();
412 
413  return ret_val;
414  }
415 
431  Node * remove(const size_t & beg, const size_t & end)
432  {
433  if (beg > end or end > COUNT(tree_root))
434  throw std::range_error("remove of TreapRk out of range");
435 
436  Node * before_beg, * after_end;
437 
438  Node * ret_val = tree_root;
439 
440  split_pos_rec(ret_val, end + 1, ret_val, after_end);
441 
442  split_pos_rec(ret_val, beg, before_beg, ret_val);
443 
444  tree_root = join_treaps(before_beg, after_end);
445 
446  return ret_val;
447  }
448 
459  Node * select(const size_t & i)
460  {
461  return Aleph::select(tree_root, i);
462  }
463 
465  size_t size() const
466  {
467  return COUNT(tree_root);
468  }
469 
471  bool is_empty() const
472  {
473  return tree_root == Node::NullPtr;
474  }
475 
488  std::pair<int, Node*> position(const Key & key)
489  {
490  std::pair<int, Node*> ret_val;
491 
492  ret_val.first = BinTreeXt_Operation<Node, Compare>(cmp).
493  inorder_position(tree_root, key, ret_val.second);
494 
495  IG(KEY(ret_val.second) == key, ret_val.first >= 0);
496 
497  return ret_val;
498  }
499 
530  std::pair<int, Node*> find_position(const Key & key)
531  {
532  std::pair<int, Node*> r(-2, NULL);
533 
534  r.first = BinTreeXt_Operation <Node, Compare>(cmp) .
535  find_position(tree_root, key, r.second);
536 
537  return r;
538  }
539 
540  bool split_key(const Key & key, Gen_Treap_Rk & t1, Gen_Treap_Rk & t2)
541  {
542  return split_key_rec_xt(tree_root, key, t1, t2);
543  }
544 
545  bool split_key_dup(const Key & key, Gen_Treap_Rk & t1, Gen_Treap_Rk & t2)
546  {
547  split_key_dup_rec_xt(tree_root, key, t1, t2);
548  }
549 
550  void split_pos(size_t pos, Gen_Treap_Rk & t1, Gen_Treap_Rk & t2)
551  {
552  split_pos_rec(tree_root, pos, t1, t2);
553  }
554 
555  void join(Gen_Treap_Rk & t, Gen_Treap_Rk & dup)
556  {
557  Node * l = (Node*) LLINK(t.tree_root);
558  Node * r = (Node*) RLINK(t.tree_root);
559 
560  t.tree_root->reset();
561  Node * ret = insert(t.tree_root);
562  if (ret == NULL)
563  dup.insert(t.tree_root);
564 
565  join(l, dup);
566  join(r, dup);
567  }
568 
569  void join_dup(Gen_Treap_Rk & t)
570  {
571  tree_root = join_treaps(tree_root, t.tree_root);
572  }
573 
582  class Iterator
583  {
584  protected:
585 
586  mutable Gen_Treap_Rk * tree_ptr;
587  mutable Node * curr;
588  mutable int curr_pos;
589 
590  static const int Pos_Not_Current = -1;
591  static const int Pos_Empty_Container = -2;
592  static const int Pos_Not_Updated = -3;
593 
594  private:
595 
596  bool is_container_empty() const
597  {
598  return COUNT(tree_ptr->getRoot()) == 0;
599  }
600 
601  bool pos_updated() const
602  {
603  return curr_pos != Pos_Not_Updated;
604  }
605 
606  bool curr_updated() const
607  {
608  return curr != NULL;
609  }
610 
611  bool is_updated()
612  {
613  return pos_updated() and curr_updated();
614  }
615 
616  void update_pos() const
617  {
618  I(curr != NULL);
619 
620  curr_pos = BinTreeXt_Operation<Node, Compare>(tree_ptr->cmp).
621  inorder_position(tree_ptr->getRoot(), KEY(curr), curr);
622  }
623 
624  void update_curr() const
625  {
626  I(curr_pos != Pos_Not_Updated);
627 
628  if (curr_pos == Pos_Empty_Container or curr_pos == Pos_Not_Current or
629  curr_pos == COUNT(tree_ptr->getRoot()))
630  return;
631 
632  curr = Aleph::select(tree_ptr->getRoot(), curr_pos);
633  }
634 
635  public:
636 
638  Iterator() : tree_ptr(NULL), curr(NULL), curr_pos(Pos_Not_Current)
639  {
640  /* empty */
641  }
642 
645  : tree_ptr(&__tree), curr(NULL)
646  {
647  curr_pos = is_container_empty() ? Pos_Empty_Container : 0;
648  }
649 
652  Iterator(Gen_Treap_Rk & __tree, Node * __curr)
653  : tree_ptr(&__tree), curr(__curr), curr_pos(Pos_Not_Updated)
654  {
655  // empty
656  }
657 
659  Iterator(Gen_Treap_Rk & __tree, const size_t & pos)
660  : tree_ptr(&__tree), curr(NULL), curr_pos(pos)
661  {
662  // empty
663  }
664 
666  Iterator(const Iterator & itor)
667  : tree_ptr(itor.tree_ptr), curr(itor.curr), curr_pos(itor.curr_pos)
668  {
669  // Empty
670  }
671 
673  Iterator & operator = (const Iterator & itor)
674  {
675  if (this == &itor)
676  return *this;
677 
678  tree_ptr = itor.tree_ptr;
679  curr = itor.curr;
680  curr_pos = itor.curr_pos;
681 
682  return *this;
683  }
684 
686  void reset_first()
687  {
688  curr = NULL;
689  curr_pos = is_container_empty() ? Pos_Empty_Container : 0;
690  }
691 
693  void reset_last()
694  {
695  curr = NULL;
696  curr_pos = (is_container_empty() ? Pos_Empty_Container :
697  COUNT(tree_ptr->getRoot()) - 1);
698  }
699 
706  void reset_to_key(const Key & key)
707  {
708  curr_pos = BinTreeXt_Operation<Node, Compare>(tree_ptr->cmp).
709  inorder_position(tree_ptr->getRoot(), key, curr);
710  }
711 
718  void reset_to_node(Node * node)
719  {
720  curr = node;
721  curr_pos = -2;
722  }
723 
725  void reset_to_pos(size_t pos)
726  {
727  curr = NULL;
728  curr_pos = pos;
729  }
730 
732  Node * get_current() const
733  {
734  if (not curr_updated())
735  update_curr();
736 
737  return curr;
738  }
739 
741  Node * get_curr() const
742  {
743  return get_current();
744  }
745 
756  size_t get_current_position() const
757  throw(std::exception, std::underflow_error, std::overflow_error)
758  {
759  if (not pos_updated())
760  update_pos();
761 
762  if (curr_pos < -1 )
763  throw std::range_error("TreapRk iterator has not current");
764 
765  if (curr_pos > COUNT(tree_ptr->getRoot() ) )
766  throw std::range_error("TreapRk iterator has not current");
767 
768  return curr_pos;
769  }
770 
773  bool has_current() const
774  {
775  if (not pos_updated())
776  update_pos();
777 
778  return curr_pos >= 0 and curr_pos < COUNT(tree_ptr->getRoot());
779  }
780 
783  bool has_curr() const
784  {
785  return has_current();
786  }
787 
789  void prev() throw(std::exception, std::underflow_error)
790  {
791  if (not has_current() )
792  throw std::underflow_error("TreapRk iterator has not current");
793 
794  --curr_pos;
795  curr = NULL;
796  }
797 
799  void next() throw(std::exception, std::overflow_error)
800  {
801  if (not has_current() )
802  throw std::underflow_error("TreapRk iterator has not current");
803 
804  ++curr_pos;
805  curr = NULL;
806  }
807 
810  Node * del()
811  {
812  if (not has_current() )
813  throw std::underflow_error("TreapRk iterator has not current");
814 
815  if (not curr_updated())
816  update_curr();
817 
818  Node * ret_val = tree_ptr->remove(KEY(curr) );
819 
820  curr = NULL;
821 
822  return ret_val;
823  }
824 
826  bool operator == (const Iterator & itor) const
827  {
828  if (is_container_empty() and itor.is_container_empty())
829  return true;
830 
831  if (pos_updated() and itor.pos_updated())
832  return curr_pos == itor.curr_pos;
833 
834  if (curr_updated() and itor.curr_updated())
835  return curr == itor.curr;
836 
837  if (not pos_updated())
838  {
839  update_pos();
840  return curr_pos == itor.curr_pos;
841  }
842 
843  itor.update_pos();
844 
845  return curr_pos == itor.curr_pos;
846  }
847 
849  bool operator != (const Iterator & itor) const
850  {
851  return not (*this == itor);
852  }
853 
854  bool verify(Gen_Treap_Rk * r) const
855  {
856  return tree_ptr->getRoot() == r->getRoot();
857  }
858 
859  bool verify(const Iterator & it) const
860  {
861  return tree_ptr->getRoot() == it.tree_ptr->getRoot();
862  }
863  }; // end class Iterator
864 };
865 
901  template <class Key, class Compare = Aleph::less<Key> >
902 class Treap_Rk : public Gen_Treap_Rk<Treap_Rk_Node, Key, Compare>
903 {
904 public:
905 
908  Treap_Rk(unsigned int seed, Compare && cmp = Compare())
909  : Gen_Treap_Rk<Treap_Rk_Node, Key, Compare>(seed, std::move(cmp))
910  {
911  // empty
912  }
913 
914  Treap_Rk(Compare && cmp = Compare())
915  : Gen_Treap_Rk<Treap_Rk_Node, Key, Compare>(time(NULL), std::move(cmp))
916  {
917  // empty
918  }
919 
920  Treap_Rk(unsigned int seed, Compare & cmp)
921  : Gen_Treap_Rk<Treap_Rk_Node, Key, Compare>(seed, cmp)
922  {
923  // empty
924  }
925 
926  Treap_Rk(Compare & cmp)
927  : Gen_Treap_Rk<Treap_Rk_Node, Key, Compare>(time(NULL), cmp)
928  {
929  // empty
930  }
931 };
932 
968  template <class Key, class Compare = Aleph::less<Key> >
969 class Treap_Rk_Vtl : public Gen_Treap_Rk<Treap_Rk_NodeVtl, Key, Compare>
970 {
971 public:
972 
975  Treap_Rk_Vtl(unsigned int seed, Compare && cmp = Compare())
976  : Gen_Treap_Rk<Treap_Rk_NodeVtl, Key, Compare>(seed, std::move(cmp))
977  {
978  // empty
979  }
980 
981  Treap_Rk_Vtl(Compare && cmp = Compare())
982  : Gen_Treap_Rk<Treap_Rk_NodeVtl, Key, Compare>(time(NULL), std::move(cmp))
983  {
984  // empty
985  }
986 
987  Treap_Rk_Vtl(unsigned int seed, Compare & cmp)
988  : Gen_Treap_Rk<Treap_Rk_NodeVtl, Key, Compare>(seed, cmp)
989  {
990  // empty
991  }
992 
993  Treap_Rk_Vtl(Compare & cmp)
994  : Gen_Treap_Rk<Treap_Rk_NodeVtl, Key, Compare>(time(NULL), cmp)
995  {
996  // empty
997  }
998 };
999 
1000 } // end namespace Aleph
1001 
1002 # endif // TPL_TREAPRK_H
void reset_last()
Reinicia el iterador al último nodo (mayor) del treap.
Definition: tpl_treapRk.H:693
Treap_Rk(unsigned int seed, Compare &&cmp=Compare())
Definition: tpl_treapRk.H:908
void reset_to_node(Node *node)
Definition: tpl_treapRk.H:718
bool operator==(const Iterator &itor) const
Retorna true si *this está sobre el mismo nodo que itor.
Definition: tpl_treapRk.H:826
#define LLINK(p)
Definition: tpl_binNode.H:196
Gen_Treap_Rk(unsigned int seed, Compare &__cmp)
Constructor; inicializa generador de números aleatorios.
Definition: tpl_treapRk.H:122
Node * get_current() const
Retorna el nodo actual.
Definition: tpl_treapRk.H:732
Definition: tpl_treapRk.H:902
std::pair< int, Node * > find_position(const Key &key)
Definition: tpl_treapRk.H:530
#define RLINK(p)
Definition: tpl_binNode.H:201
Iterator & operator=(const Iterator &itor)
Asigna al iterador this el iterador itor.
Definition: tpl_treapRk.H:673
std::pair< int, Node * > position(const Key &key)
Definition: tpl_treapRk.H:488
void next()
Avanza el iterador una posición hacia delante.
Definition: tpl_treapRk.H:799
Definition: tpl_treapRk.H:969
Definition: tpl_treapRk.H:87
Node *& getRoot()
Retorna la raíz del treap extendido.
Definition: tpl_treapRk.H:163
void reset_to_pos(size_t pos)
Coloca la posición actual del iterador en la posición pos.
Definition: tpl_treapRk.H:725
long inorder_position(Node *r, const typename Node::key_type &key, Node *&p)
Definition: tpl_binNodeXt.H:135
Gen_Treap_Rk(const Gen_Treap_Rk &)
Definition: tpl_treapRk.H:145
bool operator!=(const Iterator &itor) const
Retorna true si *this no es igual a itor.
Definition: tpl_treapRk.H:849
bool is_empty() const
Retorna true si el treap está vacío.
Definition: tpl_treapRk.H:471
Iterator(Gen_Treap_Rk &__tree, const size_t &pos)
Instancia un iterador a partir de la posición pos.
Definition: tpl_treapRk.H:659
Node * del()
Definition: tpl_treapRk.H:810
#define COUNT(p)
Definition: tpl_binNodeXt.H:34
Node * insert_dup(Node *p)
Definition: tpl_treapRk.H:308
bool has_curr() const
Definition: tpl_treapRk.H:783
size_t size() const
Retorna la cantidad de nodos que contiene el treap.
Definition: tpl_treapRk.H:465
void split_key_dup_rec_xt(Node *root, const typename Node::key_type &key, Node *&l, Node *&r)
Definition: tpl_binNodeXt.H:427
Node * rotate_to_right_xt(Node *p)
Definition: tpl_binNodeXt.H:757
Definition: tpl_binTreeOps.H:632
Definition: tpl_treapRk.H:582
NodeType< Key > Node
El tipo de nodo interno.
Definition: tpl_treapRk.H:92
Treap_Rk_Vtl(unsigned int seed, Compare &&cmp=Compare())
Definition: tpl_treapRk.H:975
Node * insert(Node *p)
Definition: tpl_treapRk.H:290
Compare & get_compare()
Definition: tpl_treapRk.H:119
Node * select(Node *r, const size_t &pos)
Definition: tpl_binNodeXt.H:89
Node * get_curr() const
Retorna el nodo actual.
Definition: tpl_treapRk.H:741
void swap(Gen_Treap_Rk &tree)
Definition: tpl_treapRk.H:155
Iterator(Gen_Treap_Rk &__tree)
Instancia un iterador a partir del menor nodo del treap __tree.
Definition: tpl_treapRk.H:644
Compare & key_comp()
Retorna una referencia al criterio de comparación.
Definition: tpl_treapRk.H:116
size_t get_current_position() const
Definition: tpl_treapRk.H:756
void reset_first()
Reinicia el iterador al primer nodo (menor) del treap.
Definition: tpl_treapRk.H:686
#define DECLARE_BINNODE_SENTINEL(Name, height, Control_Data)
Definition: tpl_binNode.H:170
void split_pos_rec(Node *r, const size_t i, Node *&ts, Node *&tg)
Definition: tpl_binNodeXt.H:541
Node * select(const size_t &i)
Definition: tpl_treapRk.H:459
Node * rotate_to_left_xt(Node *p)
Definition: tpl_binNodeXt.H:776
Iterator(const Iterator &itor)
Instancia un iterador a partir del estado del iterador itor.
Definition: tpl_treapRk.H:666
bool split_key_rec_xt(Node *root, const typename Node::key_type &key, Node *&l, Node *&r)
Definition: tpl_binNodeXt.H:373
Node * search(const Key &key)
Busca la clave key en el treap extendido this.
Definition: tpl_treapRk.H:166
#define KEY(p)
Definition: tpl_binNode.H:206
Iterator(Gen_Treap_Rk &__tree, Node *__curr)
Definition: tpl_treapRk.H:652
void prev()
Avanza el iterador una posición hacia atrás.
Definition: tpl_treapRk.H:789
Iterator()
Constructor vacío; no tiene sentido si no se asigna un treap.
Definition: tpl_treapRk.H:638
Definition: tpl_treapRk.H:14
void reset_to_key(const Key &key)
Definition: tpl_treapRk.H:706
Node * search_or_insert(Node *p)
Definition: tpl_treapRk.H:329
bool has_current() const
Definition: tpl_treapRk.H:773

Leandro Rabindranath León