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_binTreeOps.H
1 # ifndef TPL_BINTREEOPS_H
2 # define TPL_BINTREEOPS_H
3 
4 # include <tpl_binNodeUtils.H>
5 # include <tpl_binNodeXt.H>
6 
7 namespace Aleph {
8 
22  template <class Node,
24  >
26 {
27 protected:
28 
29  Cmp & cmp;
30 
31 public:
32 
34  Cmp & key_comp() { return cmp; }
35 
37  Cmp & get_compare() { return cmp; }
38 
40  typedef typename Node::key_type Key;
41 
43  typedef typename Node::key_type key_type;
44 
45  BinTree_Operation(Cmp & __cmp) : cmp(__cmp) { /* empty */ }
46 
47  BinTree_Operation(Cmp && __cmp = Cmp()) : cmp(__cmp) { /* empty */ }
48 
51  Node * search(Node * root, const Key & key)
52  {
53  return searchInBinTree <Node, Cmp> (root, key, cmp);
54  }
55 
72  Node * search_parent(Node * root, const Key & key, Node *& parent)
73  {
74  return Aleph::search_parent<Node, Cmp>(root, key, parent, cmp);
75  }
76 
93  Node * search_rank_parent(Node * root, const Key & key)
94  {
95  return Aleph::search_rank_parent<Node, Cmp>(root, key, cmp);
96  }
97 
111  Node * insert(Node *& root, Node * p)
112  {
113  if (root == Node::NullPtr)
114  return root = p;
115 
116  if (cmp(KEY(p), KEY(root))) // ¿p < root?
117  return insert((Node*&) LLINK(root), p);
118  else if (cmp(KEY(root), KEY(p))) // ¿p > root?
119  return insert((Node*&) RLINK(root), p);
120 
121  return Node::NullPtr; // clave repetida ==> no hay inserción
122  }
123 
139  Node * insert_dup(Node *& root, Node * p)
140  {
141  if (root == Node::NullPtr)
142  return root = p;
143 
144  if (cmp(KEY(p), KEY(root))) // ¿p < root?
145  return insert_dup((Node*&) LLINK(root), p);
146 
147  return insert_dup((Node*&) RLINK(root), p);
148  }
149 
166  Node * search_or_insert(Node *& r, Node * p)
167  {
168  if (r == Node::NullPtr)
169  return r = p;
170 
171  if (cmp(KEY(p), KEY(r))) // ¿p < root?
172  return search_or_insert((Node*&) LLINK(r), p);
173  else if (cmp (KEY(r), KEY(p))) // ¿p > root?
174  return search_or_insert((Node*&) RLINK(r), p);
175 
176  return r;
177  }
178 
196  bool split_key_rec(Node * root, const Key & key, Node *& ts, Node *& tg)
197  {
198  if (root == Node::NullPtr)
199  { // key no se encuentra en árbol ==> split tendrá éxito
200  ts = tg = Node::NullPtr;
201 
202  return true;
203  }
204 
205  if (cmp(key, KEY(root)) ) // ¿key < KEY(root)?
206  if (split_key_rec((Node*&) LLINK(root), key, ts, (Node*&) LLINK(root)))
207  {
208  tg = root;
209 
210  return true;
211  }
212  else
213  return false;
214 
215  if (cmp(KEY(root), key) ) // ¿key > KEY(root)?
216  if (split_key_rec((Node*&) RLINK(root), key, (Node*&) RLINK(root), tg))
217  {
218  ts = root;
219 
220  return true;
221  }
222  else
223  return false;
224 
225  return false; // clave existe en árbol ==> se deja intacto
226  }
227 
244  void split_key_dup_rec(Node * root, const typename Node::key_type & key,
245  Node *& ts, Node *& tg)
246  {
247  if (root == Node::NullPtr)
248  { // key no se encuentra en árbol ==> split tendrá éxito
249  ts = tg = Node::NullPtr;
250 
251  return;
252  }
253 
254  if (cmp(key, KEY(root))) // ¿key < KEY(root)?
255  split_key_dup_rec((Node*&) LLINK(root), key, ts, (Node*&) LLINK(root));
256  else if (cmp(KEY(root), key)) // ¿key > KEY(root)?
257  split_key_dup_rec((Node*&) RLINK(root), key, (Node*&) RLINK(root), tg);
258  else // key == KEY(root)
259  split_key_dup_rec((Node*&) LLINK(root), key, ts, (Node*&) LLINK(root));
260  }
261 
278  Node * remove(Node *& root, const Key & key)
279  {
280  if (root == Node::NullPtr)
281  return Node::NullPtr;
282 
283  if (cmp (key, KEY(root))) // ¿key < KEY(root)?
284  return remove((Node*&) LLINK(root), key);
285  else if (cmp(KEY(root), key)) // ¿key > KEY(root)?
286  return remove((Node*&) RLINK(root), key);
287 
288  Node * ret_val = root; // respaldar root que se va a borrar
289  root = join_exclusive((Node*&) LLINK(root), (Node*&) RLINK(root));
290 
291  ret_val->reset();
292 
293  return ret_val;
294  }
295 
314  Node * insert_root(Node *& root, Node * p)
315  {
316  Node * l = Node::NullPtr, * r = Node::NullPtr;
317 
318  if (not split_key_rec(root, KEY(p), l, r))
319  return Node::NullPtr;
320 
321  LLINK(p) = l;
322  RLINK(p) = r;
323  root = p;
324 
325  return root;
326  }
327 
348  Node * insert_dup_root(Node *& root, Node * p)
349  {
350  split_key_dup_rec(root, KEY(p), LLINK(p), RLINK(p));
351 
352  return root = p;
353  }
354 
372  Node * join_preorder(Node * t1, Node * t2, Node *& dup)
373  {
374  if (t2 == Node::NullPtr)
375  return t1;
376 
377  Node * l = (Node*) LLINK(t2); // respaldos de ramas de t2
378  Node * r = (Node*) RLINK(t2);
379 
380  if (insert(t1, t2) == Node::NullPtr)
381  // inserción fallida ==> elemento duplicado ==> insertar en dup
382  insert(dup, t2);
383 
384  join_preorder(t1, l, dup);
385  join_preorder(t1, r, dup);
386 
387  return t1;
388  }
389 
406  Node * join(Node * t1, Node * t2, Node *& dup)
407  {
408  if (t1 == Node::NullPtr)
409  return t2;
410 
411  if (t2 == Node::NullPtr)
412  return t1;
413 
414  Node * l = (Node*) LLINK(t1); // respaldos ramas de t1
415  Node * r = (Node*) RLINK(t1);
416 
417  t1->reset();
418 
419  // mientras la clave raíz de t1 esté contenida en t2
420  while (insert_root(t2, t1) == Node::NullPtr)
421  { // sí ==> sáquelo de t1 e insértelo en dup
422  Node * p = remove(t1, KEY(t1));
423 
424  I(p != Node::NullPtr);
425 
426  insert(dup, t1);
427  }
428 
429  LLINK(t2) = join(l, (Node*) LLINK(t2), dup);
430  RLINK(t2) = join(r, (Node*) RLINK(t2), dup);
431 
432  return t2;
433  }
434 
458  void split_key(Node * root, const Key & key, Node *& l, Node *& r)
459  {
460  if (root == Node::NullPtr)
461  {
462  l = r = (Node*) Node::NullPtr;
463 
464  return;
465  }
466 
467  Node * current;
468  Node ** current_parent = NULL;
469  Node ** pending_child = NULL;
470  char current_is_right;
471 
472  if (cmp (key, KEY(root)))
473  {
474  r = root;
475  pending_child = &l;
476  current_is_right = true;
477  }
478  else
479  {
480  l = root;
481  pending_child = &r;
482  current_is_right = false;
483  }
484 
485  current = root;
486 
487  while (current != Node::NullPtr)
488  {
489  if (cmp (key, KEY(current)))
490  { /* current must be in right side */
491  if (not current_is_right)
492  {
493  current_is_right = not current_is_right;
494  *pending_child = *current_parent; /* change of side */
495  pending_child = current_parent;
496  }
497 
498  current_parent = static_cast<Node**>(&LLINK(current));
499  }
500  else
501  { /* current must be in left side */
502  if (current_is_right)
503  {
504  current_is_right = not current_is_right;
505  *pending_child = *current_parent; /* change of side */
506  pending_child = current_parent;
507  }
508  current_parent = static_cast<Node**>(&RLINK(current));
509  }
510 
511  current = *current_parent;
512  }
513 
514  *pending_child = static_cast<Node*>(Node::NullPtr);
515  }
516 
533  Node * insert_root_rec(Node * root, Node * p)
534  {
535  if (root == Node::NullPtr)
536  return p; /* insertion in empty tree */
537 
538  if (cmp(KEY(p), KEY(root)))
539  { /* insert in left subtree */
540  Node *left_branch = insert_root_rec((Node*) LLINK(root), p);
541  if (left_branch == Node::NullPtr)
542  return (Node*) Node::NullPtr;
543 
544  LLINK(root) = left_branch;
545  root = rotate_to_right(root);
546  }
547  else if (cmp(KEY(root), KEY(p)))
548  { /* insert in right subtree */
549  Node *right_branch = insert_root_rec((Node*) RLINK(root), p);
550  if (right_branch == Node::NullPtr)
551  return (Node*) Node::NullPtr;
552 
553  RLINK(root) = right_branch;
554  root = rotate_to_left(root);
555  }
556  else
557  return (Node*) Node::NullPtr; /* duplicated key */
558 
559  return root;
560  }
561 
578  Node * search_or_insert_root_rec(Node * root, Node * p)
579  {
580  if (root == Node::NullPtr)
581  return p; // insertion in empty tree
582 
583  if (cmp(KEY(p), KEY(root)))
584  { // insert in left subtree
585  Node * left_branch = search_or_insert_root_rec((Node*) LLINK(root), p);
586  if (left_branch == p) // ¿hubo inserción?
587  {
588  LLINK(root) = left_branch;
589  root = rotate_to_right(root);
590 
591  return p;
592  }
593 
594  return left_branch; // no la hubo
595  }
596  else if (cmp(KEY(root), KEY(p)))
597  { // insert in right subtree
598  Node * right_branch = search_or_insert_root_rec((Node*) RLINK(root), p);
599  if (right_branch == p) // ¿hubo inserción?
600  {
601  RLINK(root) = right_branch;
602  root = rotate_to_left(root);
603 
604  return p;
605  }
606 
607  return right_branch; // no la hubo
608  }
609 
610  return root;
611  }
612 };
613 
614 
629  template <class Node,
631  >
632 class BinTreeXt_Operation : public BinTree_Operation<Node, Cmp>
633 {
634 public:
635 
636  typedef typename Node::key_type Key;
637 
638  BinTreeXt_Operation(Cmp && cmp = Cmp())
639  : BinTree_Operation<Node, Cmp>(std::move(cmp))
640  {
641  // empty
642  }
643 
644  BinTreeXt_Operation(Cmp & cmp)
646  {
647  // empty
648  }
649 
668  int inorder_position(Node * r, const Key & key, Node *& p)
669  {
670  I(COUNT(Node::NullPtr) == 0);
671 
672  if (r == Node::NullPtr)
673  return -1;
674 
675  if (this->cmp(key, KEY(r)))
676  return inorder_position((Node*) LLINK(r), key, p);
677  else if (this->cmp(KEY(r), key))
678  return inorder_position((Node*) RLINK(r), key, p) + COUNT(LLINK(r)) + 1;
679  else
680  {
681  p = r;
682  return COUNT(LLINK(r));
683  }
684  }
685 
725  int find_position(Node * r, const Key & key, Node *& p)
726  {
727  I(COUNT(Node::NullPtr) == 0);
728 
729  Node * parent = NULL;
730  int pos = COUNT(LLINK(r));
731 
732  while (r != Node::NullPtr)
733  if (this->cmp(key, KEY(r)))
734  {
735  parent = r;
736  r = (Node*) LLINK(r);
737  pos -= (COUNT(RLINK(r)) + 1);
738  }
739  else if (this->cmp(KEY(r), key))
740  {
741  parent = r;
742  r = (Node*) RLINK(r);
743  pos += COUNT(LLINK(r)) + 1;
744  }
745  else
746  {
747  p = r;
748  return pos;
749  }
750 
751  p = parent;
752 
753  return pos;
754  }
755 
775  bool split_key_rec(Node * root, const Key & key, Node *& l, Node *& r)
776  {
777  if (root == Node::NullPtr)
778  {
779  l = r = Node::NullPtr;
780 
781  return true;
782  }
783 
784  if (this->cmp(key, KEY(root)))
785  {
786  if (not split_key_rec(LLINK(root), key, l, LLINK(root)))
787  return false;
788 
789  r = root;
790  COUNT(r) -= COUNT(l);
791  }
792  else if (this->cmp(KEY(root), key))
793  {
794  if (not split_key_rec(RLINK(root), key, RLINK(root), r))
795  return false;
796 
797  l = root;
798  COUNT(l) -= COUNT(r);
799  }
800  else
801  return false; // clave duplicada
802 
803  return true;
804  }
805 
822  void split_key_dup_rec(Node * root, const Key & key, Node *& l, Node *& r)
823  {
824  if (root == Node::NullPtr)
825  {
826  l = r = Node::NullPtr;
827 
828  return;
829  }
830 
831  if (this->cmp(key, KEY(root)))
832  {
833  split_key_dup_rec(LLINK(root), key, l, LLINK(root));
834  r = root;
835  COUNT(r) -= COUNT(l);
836  }
837  else if (this->cmp(KEY(root), key))
838  {
839  split_key_dup_rec(RLINK(root), key, RLINK(root), r);
840  l = root;
841  COUNT(l) -= COUNT(r);
842  }
843  else
844  {
845  split_key_dup_rec(LLINK(root), key, l, LLINK(root));
846  r = root;
847  COUNT(r) -= COUNT(l);
848  }
849  }
850 
866  Node * insert_root(Node *& root, Node * p)
867  {
868  if (root == Node::NullPtr)
869  return p;
870 
871  if (not split_key_rec(root, KEY(p), LLINK(p), RLINK(p)))
872  return Node::NullPtr;
873 
874  COUNT(p) = COUNT(LLINK(p)) + COUNT(RLINK(p)) + 1;
875  root = p;
876 
877  return p;
878  }
879 
893  Node * insert_dup_root(Node *& root, Node * p)
894  {
895  if (root == Node::NullPtr)
896  return p;
897 
898  split_key_dup_rec(root, KEY(p), LLINK(p), RLINK(p));
899 
900  COUNT(p) = COUNT(LLINK(p)) + COUNT(RLINK(p)) + 1;
901 
902  return root = p;
903  }
904 };
905 
906 } // end namespace Aleph
907 
908 # endif // TPL_BINTREEOPS_H
Node * rotate_to_left(Node *p)
Definition: tpl_binNodeUtils.H:2422
#define LLINK(p)
Definition: tpl_binNode.H:196
Node::key_type Key
El tipo de clave de búsqueda.
Definition: tpl_binTreeOps.H:40
void split_key_dup_rec(Node *root, const typename Node::key_type &key, Node *&ts, Node *&tg)
Definition: tpl_binTreeOps.H:244
#define RLINK(p)
Definition: tpl_binNode.H:201
Definition: ahFunction.H:145
Node * insert(Node *&root, Node *p)
Definition: tpl_binTreeOps.H:111
Node * insert_dup_root(Node *&root, Node *p)
Definition: tpl_binTreeOps.H:893
int inorder_position(Node *r, const Key &key, Node *&p)
Definition: tpl_binTreeOps.H:668
#define COUNT(p)
Definition: tpl_binNodeXt.H:34
void split_key(Node *root, const Key &key, Node *&l, Node *&r)
Definition: tpl_binTreeOps.H:458
bool split_key_rec(Node *root, const Key &key, Node *&ts, Node *&tg)
Definition: tpl_binTreeOps.H:196
Node * rotate_to_right(Node *p)
Definition: tpl_binNodeUtils.H:2375
Node * search(Node *root, const Key &key)
Definition: tpl_binTreeOps.H:51
Definition: tpl_binTreeOps.H:632
int find_position(Node *r, const Key &key, Node *&p)
Definition: tpl_binTreeOps.H:725
Node * join_exclusive(Node *&ts, Node *&tg)
Definition: tpl_binNodeUtils.H:2155
Node * insert_root(Node *&root, Node *p)
Definition: tpl_binTreeOps.H:866
Node::key_type key_type
El tipo de clave de búsqueda.
Definition: tpl_binTreeOps.H:43
Cmp & get_compare()
Definition: tpl_binTreeOps.H:37
Cmp & key_comp()
Retorna una referencia al criterio de comparación.
Definition: tpl_binTreeOps.H:34
Node * join_preorder(Node *t1, Node *t2, Node *&dup)
Definition: tpl_binTreeOps.H:372
Node * join(Node *t1, Node *t2, Node *&dup)
Definition: tpl_binTreeOps.H:406
bool split_key_rec(Node *root, const Key &key, Node *&l, Node *&r)
Definition: tpl_binTreeOps.H:775
Node * search_or_insert_root_rec(Node *root, Node *p)
Definition: tpl_binTreeOps.H:578
void split_key_dup_rec(Node *root, const Key &key, Node *&l, Node *&r)
Definition: tpl_binTreeOps.H:822
Node * insert_root(Node *&root, Node *p)
Definition: tpl_binTreeOps.H:314
Node * insert_root_rec(Node *root, Node *p)
Definition: tpl_binTreeOps.H:533
#define KEY(p)
Definition: tpl_binNode.H:206
Node * search_rank_parent(Node *root, const Key &key)
Definition: tpl_binTreeOps.H:93
Definition: tpl_binTreeOps.H:25
Node * insert_dup(Node *&root, Node *p)
Definition: tpl_binTreeOps.H:139
Node * search_parent(Node *root, const Key &key, Node *&parent)
Definition: tpl_binTreeOps.H:72
Node * insert_dup_root(Node *&root, Node *p)
Definition: tpl_binTreeOps.H:348
Node * search_or_insert(Node *&r, Node *p)
Definition: tpl_binTreeOps.H:166

Leandro Rabindranath León