Aleph-w  1.9
General library for algorithms and data structures
tpl_binNodeUtils.H
1 
2 /* Aleph-w
3 
4  / \ | | ___ _ __ | |__ __ __
5  / _ \ | |/ _ \ '_ \| '_ \ ____\ \ /\ / / Data structures & Algorithms
6  / ___ \| | __/ |_) | | | |_____\ V V / version 1.9b
7  /_/ \_\_|\___| .__/|_| |_| \_/\_/ https://github.com/lrleon/Aleph-w
8  |_|
9 
10  This file is part of Aleph-w library
11 
12  Copyright (c) 2002-2018 Leandro Rabindranath Leon & Alejandro Mujica
13 
14  This program is free software: you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27 
28 # ifndef TPL_BINNODEUTILS_H
29 # define TPL_BINNODEUTILS_H
30 
31 # include <ahFunction.H>
32 # include <tpl_arrayStack.H>
33 # include <tpl_arrayQueue.H>
34 # include <tpl_dynListQueue.H>
35 # include <bitArray.H>
36 # include <tpl_dynDlist.H>
37 # include <tpl_binNode.H>
38 
39 using namespace Aleph;
40 namespace Aleph {
41 
42  template <class Node> inline static
43 void __inorder_rec(Node * node, const int& level, int & position,
44  void (*visitFct)(Node *, int, int))
45 {
46  if (node == Node::NullPtr)
47  return;
48 
49  __inorder_rec(LLINK(node), level + 1, position, visitFct);
50 
51  (*visitFct)(node, level, position);
52  ++position;
53 
54  __inorder_rec(RLINK(node), level + 1, position, visitFct);
55 }
56 
79  template <class Node> inline
80 int inOrderRec(Node * root, void (*visitFct)(Node*, int, int))
81 {
82  int position = 0;
83  __inorder_rec(root, 0, position, visitFct);
84  return position;
85 }
86 
87  template <class Node> inline static
88 void __preorder_rec (Node * p, const int & level, int & position,
89  void (*visitFct)(Node*, int, int))
90 {
91  if (p == Node::NullPtr)
92  return;
93 
94  (*visitFct)(p, level, position);
95  ++position;
96 
97  __preorder_rec(LLINK(p), level + 1, position, visitFct);
98  __preorder_rec(RLINK(p), level + 1, position, visitFct);
99 }
100 
123  template <class Node> inline
124 int preOrderRec(Node * root, void (*visitFct)(Node*, int, int))
125 {
126  int position = 0;
127  __preorder_rec(root, 0, position, visitFct);
128  return position;
129 }
130 
131  template <class Node> inline static
132 void __postorder_rec(Node * node, const int & level, int & position,
133  void (*visitFct)(Node*, int, int))
134 {
135  if (node == Node::NullPtr)
136  return;
137 
138  __postorder_rec(LLINK(node), level + 1, position, visitFct);
139  __postorder_rec(RLINK(node), level + 1, position, visitFct);
140 
141  (*visitFct)(node, level, position);
142  ++position;
143 }
144 
167  template <class Node> inline
168 int postOrderRec(Node * root, void (*visitFct)(Node*, int, int))
169 {
170  int position = 0;
171  __postorder_rec(root, 0, position, visitFct);
172  return position;
173 }
174 
190  template <class Node>
192 {
193  template <class Op>
194  static void for_each_inorder(Node * root, Op & op) noexcept(noexcept(op))
195  {
196  if (root == Node::NullPtr)
197  return;
198 
199  for_each_inorder(LLINK(root), op);
200  op(root);
201  for_each_inorder(RLINK(root), op);
202  }
203 
204 public:
205 
207  template <class Op>
208  void traverse(Node * root, Op & op) const noexcept(noexcept(op))
209  {
210  for_each_inorder<Op>(root, op);
211  }
212 
214  template <class Op>
215  void operator () (Node * root, Op & op) const noexcept(noexcept(op))
216  {
217  for_each_inorder<Op>(root, op);
218  }
219 
221  template <class Op>
222  void operator () (Node * root, Op && op) const noexcept(noexcept(op))
223  {
224  for_each_inorder<Op>(root, op);
225  }
226 };
227 
234  template <class Node, class Op> inline
235 void for_each_in_order(Node * root, Op && op) noexcept(noexcept(op))
236 {
237  return For_Each_In_Order<Node>().template traverse<Op>(root, op);
238 }
239 
255  template <class Node>
257 {
258  template <class Op>
259  static void preorder(Node * root, Op & op) noexcept(noexcept(op))
260  {
261  if (root == Node::NullPtr)
262  return;
263 
264  op(root);
265  preorder(LLINK(root), op);
266  preorder(RLINK(root), op);
267  }
268 
269 public:
270 
272  template <class Op>
273  void traverse(Node * root, Op & op) const noexcept(noexcept(op))
274  {
275  return preorder(root, op);
276  }
277 
279  template <class Op>
280  void operator () (Node * root, Op & op) const noexcept(noexcept(op))
281  {
282  preorder<Op>(root, op);
283  }
284 
286  template <class Op>
287  void operator () (Node * root, Op && op = Op()) const noexcept(noexcept(op))
288  {
289  preorder<Op>(root, op);
290  }
291 };
292 
299  template <class Node, class Op>
300 void for_each_preorder(Node * root, Op && op)
301 {
302  For_Each_Preorder<Node>().template traverse<Op>(root, op);
303 }
304 
305 
321  template <class Node>
323 {
324  template <class Op>
325  static void postorder(Node * root, Op & op) noexcept(noexcept(op))
326  {
327  if (root == Node::NullPtr)
328  return;
329 
330  postorder(LLINK(root), op);
331  postorder(RLINK(root), op);
332  op(root);
333  }
334 
335 public:
336 
338  template <class Op>
339  void traverse(Node * root, Op & op) const noexcept(noexcept(op))
340  {
341  return postorder(root, op);
342  }
343 
345  template <class Op>
346  void operator () (Node * root, Op & op) const noexcept(noexcept(op))
347  {
348  postorder<Op>(root, op);
349  }
350 
352  template <class Op>
353  void operator () (Node * root, Op && op = Op()) const noexcept(noexcept(op))
354  {
355  postorder<Op>(root, op);
356  }
357 };
358 
365  template <class Node, class Op>
366 void for_each_postorder(Node * root, Op && op)
367 {
368  For_Each_Postorder<Node>().template traverse<Op>(root, op);
369 }
370 
371 
372 template <class Node>
373 static void prefix(Node * root, DynList<Node*> & acc)
374 {
375  if (root == Node::NullPtr)
376  return;
377 
378  acc.append(root);
379  prefix(LLINK(root), acc);
380  prefix(RLINK(root), acc);
381 }
382 
383 template <class Node>
384 static void infix(Node * root, DynList<Node*> & acc)
385 {
386  if (root == Node::NullPtr)
387  return;
388 
389  infix(LLINK(root), acc);
390  acc.append(root);
391  infix(RLINK(root), acc);
392 }
393 
394 template <class Node>
395 static void suffix(Node * root, DynList<Node*> & acc)
396 {
397  if (root == Node::NullPtr)
398  return;
399 
400  sufffix(LLINK(root), acc);
401  siffix(RLINK(root), acc);
402  acc.append(root);
403 }
404 
412 template <class Node>
413 DynList<Node*> prefix(Node * root)
414 {
415  DynList<Node*> ret_val;
416  prefix(root, ret_val);
417  return ret_val;
418 }
419 
427 template <class Node>
428 DynList<Node*> infix(Node * root)
429 {
430  DynList<Node*> ret_val;
431  infix(root, ret_val);
432  return ret_val;
433 }
434 
442 template <class Node>
443 DynList<Node*> suffix(Node * root)
444 {
445  DynList<Node*> ret_val;
446  suffix(root, ret_val);
447  return ret_val;
448 }
449 
450 
457  template <class Node> inline
458 size_t compute_cardinality_rec(Node * root) noexcept
459 {
460  if (root == Node::NullPtr)
461  return 0;
462 
463  return (compute_cardinality_rec(LLINK(root)) + 1 +
465 }
466 
468  template <class Node> inline
469 size_t size(Node * root) noexcept
470 {
471  return compute_cardinality_rec(root);
472 }
473 
480 template <class Node> inline size_t computeHeightRec(Node * root) noexcept
481 {
482  if (root == Node::NullPtr)
483  return 0;
484 
485  const size_t left_height = computeHeightRec(LLINK(root));
486  const size_t right_height = computeHeightRec(RLINK(root));
487 
488  return 1 + std::max(left_height, right_height);
489 }
490 
499  template <class Node> inline
500 void destroyRec(Node *& root) noexcept
501 {
502  if (root == Node::NullPtr)
503  return;
504 
505  destroyRec(LLINK(root));
506  destroyRec(RLINK(root));
507  delete root;
508  root = Node::NullPtr;
509 }
510 
518  template <class Node> inline
519 Node * copyRec(Node * root)
520 {
521  if (root == Node::NullPtr)
522  return Node::NullPtr;
523 
524  Node * tgt_root = new Node(*root);
525 
526  try
527  {
528  LLINK(tgt_root) = copyRec<Node>(LLINK(root));
529  RLINK(tgt_root) = copyRec<Node>(RLINK(root));
530  }
531  catch (...)
532  {
533  assert(RLINK(tgt_root) == Node::NullPtr);
534 
535  if (LLINK(tgt_root) != Node::NullPtr)
536  destroyRec(LLINK(tgt_root)); // TODO: diff de Node*&
537 
538  delete tgt_root;
539 
540  throw;
541  }
542 
543  return tgt_root;
544 }
545 
556  template <class Node> inline
557 bool areSimilar(Node * t1, Node * t2) noexcept
558 {
559  if (t1 == t2) // that include the case when t1 and t2 are the same
560  // or both are Node::NullPtr
561  return true;
562 
563  if (t1 == Node::NullPtr or t2 == Node::NullPtr)
564  return false;
565 
566  return (areSimilar(LLINK(t1), LLINK(t2)) and
567  areSimilar(RLINK(t1), RLINK(t2)));
568 }
569 
581  template <class Node, class Equal> inline
582 bool areEquivalents(Node * t1, Node * t2, Equal & op) noexcept
583 {
584  if (t1 == t2)
585  return true;
586 
587  if (t1 == Node::NullPtr or t2 == Node::NullPtr)
588  return false;
589 
590  if (not op(KEY(t1), KEY(t2)))
591  return false;
592 
593  return (areEquivalents(LLINK(t1), LLINK(t2), op) and
594  areEquivalents(RLINK(t1), RLINK(t2), op));
595 }
596 
598 template <class Node, class Equal = std::equal_to<typename Node::key_type>>
599 inline bool areEquivalents(Node * t1, Node * t2, Equal && op = Equal()) noexcept
600 {
601  return areEquivalents(t1, t2, op);
602 }
603 
621  template <class Node> inline
622 void levelOrder(Node * root, void (*visitFct)(Node*, int, bool))
623 {
624  if (root == Node::NullPtr)
625  return;
626 
628  queue.put(std::pair<Node*, bool>(root, bool()));
629 
630  for (int pos = 0; not queue.is_empty(); pos++)
631  {
632  std::pair<Node*, bool> pr = queue.get();
633  Node *& p = pr.first;
634 
635  (*visitFct) (p, pos, pr.second);
636 
637  if (LLINK(p) != Node::NullPtr)
638  queue.put(std::pair <Node*, bool> (LLINK(p), true));
639 
640  if (RLINK(p) != Node::NullPtr)
641  queue.put(std::pair <Node*, bool> (RLINK(p), false));
642  }
643 }
644 
645 
661  template <class Node, class Operation> inline
662 bool level_traverse(Node * root, Operation & operation)
663 {
664  if (root == Node::NullPtr)
665  return true;
666 
668  queue.put(root);
669  while (not queue.is_empty())
670  {
671  Node * p = queue.get();
672  if (not operation(p))
673  return false;
674 
675  if (LLINK(p) != Node::NullPtr)
676  queue.put(LLINK(p));
677 
678  if (RLINK(p) != Node::NullPtr)
679  queue.put(RLINK(p));
680  }
681  return true;
682 }
683 
684  template <class Node, class Operation> inline
685 bool level_traverse(Node * root, Operation && operation)
686 {
687  return level_traverse<Node, Operation>(root, operation);
688 }
689 
705  template <template <class> class Node, typename Key> inline
706 Node<Key> * build_tree(const DynArray<Key> & preorder, long l_p, long r_p,
707  const DynArray<Key> & inorder, long l_i, long r_i)
708 {
709  if (l_p > r_p)
710  {
711  assert(l_i > r_i);
712  return Node<Key>::NullPtr;
713  }
714 
715  assert(r_p - l_p == r_i - l_i);
716 
717  Node<Key> * root = new Node<Key>(preorder[l_p]);
718  if (r_p == l_p)
719  return root;
720 
721  assert(l_i <= r_i);
722 
723  int i = 0;
724  for (int j = l_i; j <= r_i; ++j)
725  if (inorder[j] == preorder[l_p])
726  {
727  i = j - l_i;
728  break;
729  }
730 
731  assert(i <= r_i);
732 
733  LLINK(root) = build_tree<Node, Key>(preorder, l_p + 1, l_p + i,
734  inorder, l_i, l_i + (i - 1));
735  RLINK(root) = build_tree<Node, Key>(preorder, l_p + i + 1, r_p,
736  inorder, l_i + i + 1, r_i);
737  return root;
738 }
739 
740  template <template <class> class Node, typename Key> inline
741 Node<Key> * build_postorder(const DynArray<Key> & post, long lp, long rp,
742  const DynArray<Key> & in, long li, long ri)
743 {
744  assert(rp - lp == ri - li);
745  if (lp > rp)
746  return Node<Key>::NullPtr;
747 
748  Node<Key> * root = new Node<Key>(post[rp]);
749 
750  int i = li;
751  for (; i <= ri; ++i) // search in inorder array the index of root
752  if (in[i] == post[rp])
753  break;
754 
755  assert(i <= ri);
756 
757  LLINK(root) = build_postorder<Node, Key>(post, lp, lp + (i - li) - 1,
758  in, li, i - 1);
759  RLINK(root) = build_postorder<Node, Key>(post, rp - (ri - i), rp - 1,
760  in, i + 1, ri);
761  return root;
762 }
763 
764  template <class Node> inline static void
765 __compute_nodes_in_level(Node * root, long level, long current_level,
766  DynDlist<Node*> & level_list)
767 {
768  if (root == Node::NullPtr)
769  return;
770 
771  if (current_level == level)
772  {
773  level_list.append(root);
774  return; // no vale la pena descender m�s
775  }
776 
777  __compute_nodes_in_level(LLINK(root), level, current_level + 1, level_list);
778  __compute_nodes_in_level(RLINK(root), level, current_level + 1, level_list);
779 }
780 
789  template <class Node> inline
790 DynDlist<Node*> compute_nodes_in_level(Node * root, const int & level)
791 {
793  __compute_nodes_in_level(root, level, 0, list);
794  return list;
795 }
796 
818  template <class Node> inline
819 void inOrderThreaded(Node * root, void (*visitFct)(Node*))
820 {
821  if (root == Node::NullPtr)
822  return;
823 
824  Node *p = root, *r = Node::NullPtr, *q;
825  while (p != Node::NullPtr)
826  {
827  q = LLINK(p);
828  if (q == Node::NullPtr)
829  { // No hay rama izq ==> visitar p
830  (*visitFct)(p);
831  r = p;
832  p = RLINK(p);
833  continue;
834  }
835 
836  // avanzar hacia el nodo m�s a la derecha de la rama izquierda
837  while (q != r and RLINK(q) != Node::NullPtr)
838  q = RLINK(q);
839 
840  if (q != r) // tiene p un predecesor?
841  { // si ==> dejar un hilo para luego subir a visitar p
842  RLINK(q) = p; // Aqu� se coloca el hilo
843  p = LLINK(p); // Seguir bajando por la izquierda
844  continue;
845  }
846 
847  (*visitFct)(p);
848 
849  RLINK(q) = Node::NullPtr; // Borrar hilo
850  r = p;
851  p = RLINK(p); // avanzar a la rama derecha
852  }
853 }
854 
876  template <class Node> inline
877 void preOrderThreaded(Node * node, void (*visitFct)(Node*))
878 {
879  if (node == Node::NullPtr)
880  return;
881 
882  Node * p = node, * r = Node::NullPtr, *q;
883  while (p != Node::NullPtr)
884  {
885  q = LLINK(p);
886 
887  if (q == Node::NullPtr)
888  {
889  (*visitFct)(p);
890  r = p;
891  p = RLINK(p);
892  continue;
893  }
894 
895  // avanzar hacia el nodo m�s a la derecha de la rama izquierda
896  while (q != r and RLINK(q) != Node::NullPtr)
897  q = RLINK(q);
898 
899  if (q != r)
900  {
901  RLINK(q) = p;
902  (*visitFct)(p);
903  p = LLINK(p);
904  continue;
905  }
906 
907  RLINK(q) = Node::NullPtr; /* delete thread */
908  r = p;
909  p = RLINK(p); /* advance to right branch */
910  }
911 }
912 
913  template <class Node> inline static
914 size_t __internal_path_length(Node * p, const size_t & level) noexcept
915 {
916  if (p == Node::NullPtr)
917  return 0;
918 
919  return level + __internal_path_length(LLINK(p), level + 1) +
920  __internal_path_length(RLINK(p), level + 1);
921 }
922 
930  template <class Node> inline
931 size_t internal_path_length(Node * p) noexcept
932 {
933  return __internal_path_length(p, 0);
934 }
935 
949  template <class Node> inline
950 void tree_to_bits(Node * root, BitArray & array)
951 {
952  if (root == Node::NullPtr)
953  {
954  array.push(1);
955  return;
956  }
957 
958  array.push(0);
959  tree_to_bits(LLINK(root), array);
960  tree_to_bits(RLINK(root), array);
961 }
962 
976 template <class Node> inline
977 BitArray tree_to_bits(Node * root)
978 {
979  BitArray ret_val;
980  tree_to_bits(root, ret_val);
981  return ret_val;
982 }
983 
991 template <class Node> inline string code(Node * root)
992 {
993  BitArray bits = tree_to_bits(root);
994  const size_t n = bits.size();
995  string str(""); str.reserve(n);
996  for (size_t i = 0; i < n; ++i)
997  str.push_back(bits(i) ? 'b' : 'a');
998 
999  return str;
1000 }
1001 
1002  template <class Node> static inline
1003 Node * __bits_to_tree(const BitArray & array, int & i)
1004 {
1005  int bit = array.read_bit(i++);
1006  if (bit == 1)
1007  return Node::NullPtr;
1008 
1009  Node * p = new Node;
1010  LLINK(p) = __bits_to_tree<Node>(array, i);
1011  RLINK(p) = __bits_to_tree<Node>(array, i);
1012 
1013  return p;
1014 }
1015 
1029 template <class Node> inline
1030 Node * bits_to_tree(const BitArray & array, int idx = 0)
1031 {
1032  return __bits_to_tree <Node>(array, idx);
1033 }
1034 
1052  template <class Node> inline
1053 void save_tree_keys_in_prefix(Node * root, ostream & output)
1054 {
1055  if (root == Node::NullPtr)
1056  return;
1057 
1058  output << root->get_key() << " ";
1059 
1060  save_tree_keys_in_prefix(LLINK(root), output);
1061  save_tree_keys_in_prefix(RLINK(root), output);
1062 }
1063 
1073  template <class Node> inline
1074 void load_tree_keys_in_prefix(Node * root, istream & input)
1075 {
1076  if (root == Node::NullPtr)
1077  return;
1078 
1079  input >> root->get_key();
1080 
1081  load_tree_keys_in_prefix(LLINK(root), input);
1082  load_tree_keys_in_prefix(RLINK(root), input);
1083 }
1084 
1085 
1100  template <class Node> inline
1101 void save_tree(Node * root, ostream & output)
1102 {
1103  BitArray prefix;
1104  tree_to_bits(root, prefix);
1105  prefix.save(output);
1106  save_tree_keys_in_prefix(root, output);
1107 }
1108 
1109 
1121  template <class Node> inline
1122 Node * load_tree(istream & input)
1123 {
1124  BitArray prefix;
1125  prefix.load(input);
1126  Node * root = bits_to_tree <Node> (prefix);
1127  load_tree_keys_in_prefix(root, input);
1128  return root;
1129 }
1130 
1131 
1132  template <class Node, class Get_Key> inline
1133 void put_tree_keys_in_array(Node * root, ostream & out)
1134 {
1135  if (root == Node::NullPtr)
1136  return;
1137 
1138  const string str = Get_Key () (root);
1139 
1140  if (str == "\t")
1141  out << "\"\t\"";
1142  else if (str == "\n")
1143  out << "\"\\n\"";
1144  else
1145  out << "\"" << str << "\"";
1146  out << ", ";
1147 
1148  put_tree_keys_in_array<Node, Get_Key>(LLINK(root), out);
1149  put_tree_keys_in_array<Node, Get_Key>(RLINK(root), out);
1150 }
1151 
1152 
1153  template <class Node, class Load_Key> inline
1154 void load_tree_keys_from_array(Node * root, const char * keys[], int & idx)
1155 {
1156  if (root == Node::NullPtr)
1157  return;
1158 
1159  if (Load_Key()(root, keys[idx]))
1160  ++idx;
1161 
1162  load_tree_keys_from_array<Node, Load_Key>(LLINK(root), keys, idx);
1163  load_tree_keys_from_array<Node, Load_Key>(RLINK(root), keys, idx);
1164 }
1165 
1194  template <class Node, class Get_Key> inline
1196  const string & array_name,
1197  ostream & output)
1198  {
1199  BitArray prefix;
1200  tree_to_bits(root, prefix);
1201  prefix.save_in_array_of_chars(array_name + "_cdp", output);
1202  output << "const char * " << array_name << "_k[] = { " << endl;
1203  put_tree_keys_in_array <Node, Get_Key> (root, output);
1204  output << "nullptr };" << endl;
1205  }
1206 
1207 
1237  template <class Node, class Load_Key> inline
1238 Node * load_tree_from_array(const unsigned char bits[],
1239  const size_t & num_bits,
1240  const char * keys[])
1241 {
1242  BitArray prefix;
1243  prefix.load_from_array_of_chars(bits, num_bits);
1244  Node * root = bits_to_tree <Node> (prefix);
1245  int i = 0;
1246  load_tree_keys_from_array <Node, Load_Key> (root, keys, i);
1247  return root;
1248 }
1249 
1250 
1260  template <class Node,
1261  class Compare = Aleph::less<typename Node::key_type>> inline
1262 bool check_bst(Node * p, Compare cmp = Compare())
1263 {
1264  if (p == Node::NullPtr)
1265  return true;
1266 
1267  if (LLINK(p) != Node::NullPtr and
1268  (not less_or_equal_than(KEY(LLINK(p)), KEY(p), cmp) or
1269  not check_bst(LLINK(p), cmp)))
1270  return false;
1271 
1272  if (RLINK(p) != Node::NullPtr and
1273  (not less_or_equal_than(KEY(p), KEY(RLINK(p)), cmp) or
1274  not check_bst(RLINK(p), cmp)))
1275  return false;
1276 
1277  return true;
1278 }
1279 
1280 
1291  template <class Node> inline Node *
1293 {
1294  if (l > r)
1295  return Node::NullPtr;
1296 
1297  Node * root = new Node(preorder[l]);
1298 
1299  if (l == r)
1300  return root;
1301 
1302  int first_greater = l + 1;
1303  while ((first_greater <= r) and (preorder[first_greater] < preorder[l]))
1304  ++first_greater;
1305 
1306  LLINK(root) = preorder_to_bst<Node>(preorder, l + 1, first_greater - 1);
1307  RLINK(root) = preorder_to_bst<Node>(preorder, first_greater, r);
1308 
1309  return root;
1310 }
1311 
1321  template <class Node,
1322  class Compare = Aleph::less<typename Node::key_type>> inline
1323 Node * searchInBinTree(Node * root, const typename Node::key_type & key,
1324  Compare cmp = Compare()) noexcept
1325 {
1326  while (root != Node::NullPtr)
1327  if (cmp(key, KEY(root)))
1328  root = LLINK(root);
1329  else if(cmp(KEY(root), key))
1330  root = RLINK(root);
1331  else
1332  break;
1333 
1334  return root;
1335 }
1336 
1345  template <class Node> inline
1346 Node * find_min(Node * root) noexcept
1347 {
1348  while (LLINK(root) != Node::NullPtr)
1349  root = LLINK(root);
1350 
1351  return root;
1352 }
1353 
1362  template <class Node> inline
1363 Node * find_max(Node * root) noexcept
1364 {
1365  while (RLINK(root) != Node::NullPtr)
1366  root = RLINK(root);
1367 
1368  return root;
1369 }
1370 
1379  template <class Node> inline
1380 Node * find_successor(Node * p, Node *& pp) noexcept
1381 {
1382  assert(p != Node::NullPtr);
1383  assert(RLINK(p) != Node::NullPtr);
1384 
1385  pp = p;
1386  p = RLINK(p);
1387  while (LLINK(p) != Node::NullPtr)
1388  {
1389  pp = p;
1390  p = LLINK(p);
1391  }
1392 
1393  return p;
1394 }
1395 
1404  template <class Node> inline
1405 Node* find_predecessor(Node * p, Node *& pp) noexcept
1406 {
1407  assert(p != Node::NullPtr);
1408  assert(LLINK(pp) != Node::NullPtr);
1409 
1410  pp = p;
1411  p = LLINK(p);
1412 
1413  while (RLINK(p) != Node::NullPtr)
1414  {
1415  pp = p;
1416  p = RLINK(p);
1417  }
1418 
1419  return p;
1420 }
1421 
1434  template <class Node,
1435  class Compare = Aleph::less<typename Node::key_type>> inline
1436 Node * search_parent(Node * root, const typename Node::key_type & key,
1437  Node *& parent, Compare cmp = Compare()) noexcept
1438 {
1439  assert((LLINK(parent) == root) or (RLINK(parent) == root));
1440  assert(root != Node::NullPtr);
1441 
1442  while (true)
1443  if (cmp(key, KEY(root)))
1444  {
1445  if (LLINK(root) == Node::NullPtr)
1446  return root;
1447 
1448  parent = root;
1449  root = LLINK(root);
1450  }
1451  else if (cmp(KEY(root), key))
1452  {
1453  if (RLINK(root) == Node::NullPtr)
1454  return root;
1455 
1456  parent = root;
1457  root = RLINK(root);
1458  }
1459  else
1460  return root;
1461 }
1462 
1481  template <class Node,
1482  class Compare = Aleph::less<typename Node::key_type>>
1483  inline Node *
1484 search_rank_parent(Node * root, const typename Node::key_type & key,
1485  Compare cmp = Compare()) noexcept
1486 {
1487  assert(root != Node::NullPtr);
1488 
1489  while (true)
1490  if (cmp(key, KEY(root)))
1491  {
1492  if (LLINK(root) == Node::NullPtr)
1493  return root;
1494 
1495  root = LLINK(root);
1496  }
1497  else if (cmp(KEY(root), key))
1498  {
1499  if (RLINK(root) == Node::NullPtr)
1500  return root;
1501 
1502  root = RLINK(root);
1503  }
1504  else
1505  return root;
1506 }
1507 
1520 template <class Node,
1521  class Compare = Aleph::less<typename Node::key_type>> inline
1522 Node * insert_in_bst(Node *& r, Node * p, Compare cmp = Compare()) noexcept
1523 {
1524  if (r == Node::NullPtr)
1525  return r = p;
1526 
1527  if (cmp(KEY(p), KEY(r)))
1528  return insert_in_bst<Node,Compare>(LLINK(r), p, cmp);
1529  else if (cmp(KEY(r), KEY(p)))
1530  return insert_in_bst<Node,Compare>(RLINK(r), p, cmp);
1531 
1532  return Node::NullPtr;
1533 }
1534 
1547  template <class Node,
1548  class Compare = Aleph::less<typename Node::key_type>> inline
1549 Node * insert_dup_in_bst(Node *& root, Node * p, Compare cmp = Compare())
1550  noexcept
1551 {
1552  if (root == Node::NullPtr)
1553  return root = p;
1554 
1555  if (cmp(KEY(p), KEY(root)))
1556  return insert_dup_in_bst(LLINK(root), p, cmp);
1557 
1558  return insert_dup_in_bst(RLINK(root), p, cmp);
1559 }
1560 
1575  template <class Node,
1576  class Compare = Aleph::less<typename Node::key_type>> inline
1577 Node * search_or_insert_in_bst(Node *& r, Node * p, Compare cmp = Compare())
1578  noexcept
1579 {
1580  if (r == Node::NullPtr)
1581  return r = p;
1582 
1583  if (cmp(KEY(p), KEY(r)))
1584  return search_or_insert_in_bst<Node, Compare>(LLINK(r), p, cmp);
1585  else if (cmp(KEY(r), KEY(p)))
1586  return search_or_insert_in_bst<Node, Compare>(RLINK(r), p, cmp);
1587 
1588  return r;
1589 }
1590 
1591 
1592  template <class Node, class Compare> static inline
1593 bool __split_key_rec(Node * root, const typename Node::key_type & key,
1594  Node *& ts, Node *& tg, Compare & cmp) noexcept
1595 {
1596  if (root == Node::NullPtr)
1597  { // key no se encuentra en árbol ==> split tendr� �xito
1598  ts = tg = Node::NullPtr;
1599  return true;
1600  }
1601 
1602  if (cmp(key, KEY(root)))
1603  if (__split_key_rec(LLINK(root), key, ts, LLINK(root), cmp))
1604  {
1605  tg = root;
1606  return true;
1607  }
1608  else
1609  return false;
1610 
1611  if (cmp(KEY(root), key))
1612  if (__split_key_rec(RLINK(root), key, RLINK(root), tg, cmp))
1613  {
1614  ts = root;
1615  return true;
1616  }
1617 
1618  return false; // key exists in the tree
1619 }
1620 
1621 
1641  template <class Node,
1642  class Compare = Aleph::less<typename Node::key_type>> inline
1643 bool split_key_rec(Node *& root, const typename Node::key_type & key,
1644  Node *& ts, Node *& tg, Compare cmp = Compare()) noexcept
1645 {
1646  bool ret = __split_key_rec(root, key, ts, tg, cmp);
1647  if (ret)
1648  root = Node::NullPtr;
1649  return ret;
1650 }
1651 
1652 
1653  template <class Node, class Compare> static inline
1654 void __split_key_dup_rec(Node * root, const typename Node::key_type & key,
1655  Node *& ts, Node *& tg, Compare & cmp) noexcept
1656 {
1657  if (root == Node::NullPtr)
1658  {
1659  ts = tg = Node::NullPtr;
1660  return;
1661  }
1662 
1663  if (cmp(KEY(root), key))
1664  __split_key_dup_rec(RLINK(root), key, RLINK(root), tg, cmp);
1665  else
1666  __split_key_dup_rec(LLINK(root), key, ts, LLINK(root), cmp);
1667 }
1668 
1669 
1684  template <class Node,
1685  class Compare = Aleph::less<typename Node::key_type>> inline
1686 void split_key_dup_rec(Node *& root, const typename Node::key_type & key,
1687  Node *& ts, Node *& tg, Compare cmp = Compare()) noexcept
1688 {
1689  __split_key_dup_rec(root, key, ts, tg, cmp);
1690  root = Node::NullPtr;
1691 }
1692 
1693 
1707 template <class Node> inline
1708 Node * join_exclusive(Node *& ts, Node *& tg) noexcept
1709 {
1710  if (ts == Node::NullPtr)
1711  return tg;
1712 
1713  if (tg == Node::NullPtr)
1714  return ts;
1715 
1716  LLINK(tg) = join_exclusive(RLINK(ts), LLINK(tg));
1717 
1718  RLINK(ts) = tg;
1719  Node * ret_val = ts;
1720  ts = tg = Node::NullPtr; // empty the trees
1721 
1722  return ret_val;
1723 }
1724 
1736  template <class Node,
1737  class Compare = Aleph::less<typename Node::key_type>> inline
1738 Node * remove_from_bst(Node *& root, const typename Node::key_type & key,
1739  Compare cmp = Compare()) noexcept
1740 {
1741  if (root == Node::NullPtr)
1742  return Node::NullPtr;
1743 
1744  if (cmp(key, KEY(root)))
1745  return remove_from_bst(LLINK(root), key);
1746  else if (cmp(KEY(root), key))
1747  return remove_from_bst(RLINK(root), key);
1748 
1749  Node * ret_val = root; // respaldar root que se va a borrar
1750  root = join_exclusive(LLINK(root), RLINK(root));
1751 
1752  ret_val->reset();
1753 
1754  return ret_val;
1755 }
1756 
1771  template <class Node,
1772  class Compare = Aleph::less<typename Node::key_type>> inline
1773 Node * insert_root(Node *& root, Node * p, Compare cmp = Compare()) noexcept
1774 {
1775  Node * l = Node::NullPtr, * r = Node::NullPtr;
1776 
1777  if (not split_key_rec(root, KEY(p), l, r, cmp))
1778  return Node::NullPtr;
1779 
1780  LLINK(p) = l;
1781  RLINK(p) = r;
1782  root = p;
1783 
1784  return root;
1785 }
1786 
1797  template <class Node,
1798  class Compare = Aleph::less<typename Node::key_type>> inline
1799 Node * insert_dup_root(Node *& root, Node * p, Compare cmp = Compare()) noexcept
1800 {
1801  split_key_dup_rec(root, KEY(p), LLINK(p), RLINK(p), cmp);
1802  return root = p;
1803 }
1804 
1805 
1819  template <class Node,
1820  class Compare = Aleph::less<typename Node::key_type>> inline
1821 Node * join_preorder(Node * t1, Node * t2, Node *& dup, Compare cmp = Compare())
1822  noexcept
1823 {
1824  if (t2 == Node::NullPtr)
1825  return t1;
1826 
1827  Node * l = LLINK(t2);
1828  Node * r = RLINK(t2);
1829 
1830  if (insert_in_bst(t1, t2, cmp) == Node::NullPtr)
1831  insert_in_bst(dup, t2, cmp); // insertion has failed
1832 
1833  join_preorder(t1, l, dup, cmp);
1834  join_preorder(t1, r, dup, cmp);
1835 
1836  return t1;
1837 }
1838 
1853  template <class Node,
1854  class Compare = Aleph::less<typename Node::key_type>> inline
1855 Node * join(Node * t1, Node * t2, Node *& dup, Compare cmp = Compare()) noexcept
1856 {
1857  if (t1 == Node::NullPtr)
1858  return t2;
1859 
1860  if (t2 == Node::NullPtr)
1861  return t1;
1862 
1863  Node * l = LLINK(t1);
1864  Node * r = RLINK(t1);
1865 
1866  t1->reset();
1867 
1868  while (t1 != Node::NullPtr and insert_root(t2, t1, cmp) == Node::NullPtr)
1869  {
1870  Node * p = remove_from_bst(t1, KEY(t1), cmp);
1871  l = LLINK(t1);
1872  r = RLINK(t1);
1873 
1874  assert(p != Node::NullPtr);
1875 
1876  insert_in_bst(dup, p, cmp);
1877  }
1878 
1879  LLINK(t2) = join(l, LLINK(t2), dup, cmp);
1880  RLINK(t2) = join(r, RLINK(t2), dup, cmp);
1881 
1882  return t2;
1883 }
1884 
1890  template <class Node> inline
1891 Node * rotate_to_right(Node * p) noexcept
1892 {
1893  assert(p != Node::NullPtr);
1894 
1895  Node * q = LLINK(p);
1896  LLINK(p) = RLINK(q);
1897  RLINK(q) = p;
1898 
1899  return q;
1900 }
1901 
1907  template <class Node> inline
1908 Node * rotate_to_right(Node * p, Node * pp) noexcept
1909 {
1910  assert(p != Node::NullPtr);
1911  assert(pp != Node::NullPtr);
1912  assert(LLINK(pp) == p or RLINK(pp) == p);
1913 
1914  Node * q = LLINK(p);
1915  LLINK(p) = RLINK(q);
1916  RLINK(q) = p;
1917 
1918  if (LLINK(pp) == p) // actualización del padre
1919  LLINK(pp) = q;
1920  else
1921  RLINK(pp) = q;
1922 
1923  return q;
1924 }
1925 
1931  template <class Node> inline
1932 Node* rotate_to_left(Node * p) noexcept
1933 {
1934  assert(p != Node::NullPtr);
1935 
1936  Node *q = RLINK(p);
1937  RLINK(p) = LLINK(q);
1938  LLINK(q) = p;
1939 
1940  return q;
1941 }
1942 
1948  template <class Node> inline
1949 Node* rotate_to_left(Node * p, Node * pp) noexcept
1950 {
1951  assert(p != Node::NullPtr);
1952  assert(pp != Node::NullPtr);
1953  assert(LLINK(pp) == p or RLINK(pp) == p);
1954 
1955  Node *q = RLINK(p);
1956  RLINK(p) = LLINK(q);
1957  LLINK(q) = p;
1958 
1959  // actualización del padre
1960  if (LLINK(pp) == p)
1961  LLINK(pp) = q;
1962  else
1963  RLINK(pp) = q;
1964 
1965  return q;
1966 }
1967 
1982  template <class Node, class Key,
1983  class Compare = Aleph::less<typename Node::key_type>> inline
1984 void split_key(Node *& root, const Key & key, Node *& l, Node *& r,
1985  Compare cmp = Compare()) noexcept
1986 {
1987  assert(l == Node::NullPtr and r == Node::NullPtr);
1988  if (root == Node::NullPtr)
1989  {
1990  l = r = Node::NullPtr;
1991  return;
1992  }
1993 
1994  Node ** current_parent = nullptr;
1995  Node ** pending_child = nullptr;
1996  char current_is_right = true;
1997  if (cmp(key, KEY(root)))
1998  {
1999  r = root;
2000  pending_child = &l;
2001  }
2002  else
2003  {
2004  l = root;
2005  pending_child = &r;
2006  current_is_right = false;
2007  }
2008 
2009  Node * current = root;
2010  while (current != Node::NullPtr)
2011  {
2012  if (cmp (key, KEY(current)))
2013  { /* current must be in right side */
2014  if (not current_is_right)
2015  {
2016  current_is_right = not current_is_right;
2017  *pending_child = *current_parent; /* change of side */
2018  pending_child = current_parent;
2019  }
2020  current_parent = &LLINK(current);
2021  }
2022  else
2023  { /* current must be in left side */
2024  if (current_is_right)
2025  {
2026  current_is_right = not current_is_right;
2027  *pending_child = *current_parent; /* change of side */
2028  pending_child = current_parent;
2029  }
2030  current_parent = &RLINK(current);
2031  }
2032  current = *current_parent;
2033  }
2034  *pending_child = Node::NullPtr;
2035  root = Node::NullPtr;
2036 }
2037 
2047  template <class Node> inline
2048 void swap_node_with_successor(Node * p, // Node for swapping
2049  Node *& pp, // parent of p
2050  Node * q, // Successor inorder of p
2051  Node *& pq) // parent of q
2052  noexcept
2053 {
2054  assert(p != Node::NullPtr and q != Node::NullPtr and
2055  pp != Node::NullPtr and pq != Node::NullPtr);
2056  assert(LLINK(pp) == p or RLINK(pp) == p);
2057  assert(LLINK(pq) == q or RLINK(pq) == q);
2058  assert(LLINK(q) == Node::NullPtr);
2059 
2060  /* Set of pp to its new son q */
2061  if (LLINK(pp) == p)
2062  LLINK(pp) = q;
2063  else
2064  RLINK(pp) = q;
2065 
2066  LLINK(q) = LLINK(p);
2067  LLINK(p) = Node::NullPtr;
2068 
2069  /* Checks if successor is right child of p. In this case, p will
2070  become q's son. This situation happens when p's son does not have
2071  a left branch */
2072  if (RLINK(p) == q)
2073  {
2074  RLINK(p) = RLINK(q);
2075  RLINK(q) = p;
2076  pq = pp;
2077  pp = q;
2078  return;
2079  }
2080 
2081  /* In this case, successor is the leftmost node descending from
2082  right son of p */
2083  Node *qr = RLINK(q);
2084  RLINK(q) = RLINK(p);
2085  LLINK(pq) = p;
2086  RLINK(p) = qr;
2087 
2088  std::swap(pp, pq);
2089 }
2090 
2100  template <class Node> inline
2101 void swap_node_with_predecessor(Node * p, // Node for swapping
2102  Node *& pp, // p's parent
2103  Node * q, // Predecessor inorder of p
2104  Node *& pq) // q's parent
2105  noexcept
2106 {
2107  assert((p != Node::NullPtr) and (q != Node::NullPtr) and
2108  (pp != Node::NullPtr) and (pq != Node::NullPtr));
2109  assert((RLINK(pp) == p) or (LLINK(pp) == p));
2110  assert((RLINK(pq) == q) or (LLINK(pq) == q));
2111  assert(RLINK(q) == Node::NullPtr);
2112 
2113  /* Set of pp to its new son q */
2114  if (RLINK(pp) == p)
2115  RLINK(pp) = q;
2116  else
2117  LLINK(pp) = q;
2118 
2119  RLINK(q) = RLINK(p);
2120  RLINK(p) = Node::NullPtr;
2121 
2122  /* Checks if predecessor is left child of p. In this case, p will
2123  become q's son. This situation happens when p's son does not have
2124  a right branch */
2125  if (LLINK(p) == q)
2126  {
2127  LLINK(p) = LLINK(q);
2128  LLINK(q) = p;
2129  pq = pp;
2130  pp = q;
2131  return;
2132  }
2133 
2134  /* In this case, predecessor is the rightmost node descending from
2135  right son of p */
2136  Node *ql = LLINK(q);
2137  LLINK(q) = LLINK(p);
2138  RLINK(pq) = p;
2139  LLINK(p) = ql;
2140  std::swap(pp, pq);
2141 }
2142 
2156  template <class Node, class Key,
2157  class Compare = Aleph::less<typename Node::key_type>> inline
2158 Node * insert_root_rec(Node * root, Node * p, Compare cmp = Compare()) noexcept
2159 {
2160  if (root == Node::NullPtr)
2161  return p; /* insertion in empty tree */
2162 
2163  if (cmp(KEY(p), KEY(root)))
2164  { /* insert in left subtree */
2165  Node *left_branch = insert_root_rec(LLINK(root), p, cmp);
2166  if (left_branch == Node::NullPtr)
2167  return Node::NullPtr;
2168 
2169  LLINK(root) = left_branch;
2170  root = rotate_to_right(root);
2171  }
2172  else if (cmp(KEY(root), KEY(p)))
2173  { /* insert in right subtree */
2174  Node *right_branch = insert_root_rec(RLINK(root), p, cmp);
2175  if (right_branch == Node::NullPtr)
2176  return Node::NullPtr;
2177 
2178  RLINK(root) = right_branch;
2179  root = rotate_to_left(root);
2180  }
2181 
2182  return Node::NullPtr; /* duplicated key */
2183 }
2184 
2195  template <class Node, class Key,
2196  class Compare = Aleph::less<typename Node::key_type> > inline
2197 Node * search_or_insert_root_rec(Node * root, Node * p, Compare cmp = Compare())
2198  noexcept
2199 {
2200  if (root == Node::NullPtr)
2201  return p; // insertion in empty tree
2202 
2203  if (cmp(KEY(p), KEY(root)))
2204  { // insert in left subtree
2205  Node * left_branch = search_or_insert_root_rec(LLINK(root), p, cmp);
2206  if (left_branch == p)
2207  {
2208  LLINK(root) = left_branch;
2209  root = rotate_to_right(root);
2210  return p;
2211  }
2212 
2213  return left_branch;
2214  }
2215  else if (cmp(KEY(root), KEY(p)))
2216  { // insert in right subtree
2217  Node * right_branch = search_or_insert_root_rec(RLINK(root), p, cmp);
2218  if (right_branch == p)
2219  {
2220  RLINK(root) = right_branch;
2221  root = rotate_to_left(root);
2222  return p;
2223  }
2224 
2225  return right_branch;
2226  }
2227 
2228  return root;
2229 }
2230 
2231 
2239 template <class Node>
2241 {
2242  Node * root = nullptr;
2243  Node * curr = Node::NullPtr;
2245 
2246 public:
2247 
2250  {
2251  std::swap(root, it.root);
2252  std::swap(curr, it.curr);
2253  s.swap(it.s);
2254  }
2255 
2256  BinNodePrefixIterator() noexcept { /* empty */ }
2257 
2260  BinNodePrefixIterator(Node * __root) noexcept
2261  : root(__root), curr(root), s(Node::MaxHeight)
2262  {
2263  // empty
2264  }
2265 
2267  : root(it.root), curr(it.curr), s(it.s)
2268  {
2269  // empty
2270  }
2271 
2273  {
2274  swap(it);
2275  }
2276 
2278  void reset_first() noexcept
2279  {
2280  curr = root;
2281  s.empty();
2282  }
2283 
2284 private:
2285 
2286  // Helper function for finding last node
2287  static Node * last(Node * p) noexcept
2288  {
2289  if (RLINK(p) != Node::NullPtr)
2290  return last(RLINK(p));
2291 
2292  if (LLINK(p) != Node::NullPtr)
2293  return last(LLINK(p));
2294 
2295  return p;
2296  }
2297 
2298 public:
2299 
2301  void reset_last() noexcept
2302  {
2303  curr = last(root);
2304  s.empty();
2305  }
2306 
2308  void end() noexcept
2309  {
2310  curr = Node::NullPtr;
2311  s.empty();
2312  }
2313 
2314  BinNodePrefixIterator & operator = (const BinNodePrefixIterator & it)
2315  {
2316  if (this == &it)
2317  return *this;
2318 
2319  root = it.root;
2320  curr = it.curr;
2321  s = it.s;
2322  return *this;
2323  }
2324 
2325  BinNodePrefixIterator & operator = (BinNodePrefixIterator && it)
2326  {
2327  swap(it);
2328  return *this;
2329  }
2330 
2332  bool has_curr() const noexcept { return curr != Node::NullPtr; }
2333 
2335  Node * get_curr_ne() const noexcept { return curr; }
2336 
2338  Node * get_curr() const
2339  {
2340  if (not has_curr())
2341  throw std::overflow_error("Iterator overflow");
2342  return get_curr_ne();
2343  }
2344 
2347  void next_ne() noexcept
2348  {
2349  auto l = LLINK(curr), r = RLINK(curr);
2350  if (l != Node::NullPtr)
2351  {
2352  curr = l;
2353  if (r != Node::NullPtr)
2354  s.push(r);
2355  return;
2356  }
2357 
2358  if (r != Node::NullPtr)
2359  {
2360  curr = r;
2361  return;
2362  }
2363 
2364  if (s.is_empty())
2365  curr = Node::NullPtr;
2366  else
2367  curr = s.pop();
2368  }
2369 
2371  void next()
2372  {
2373  if (not has_curr())
2374  throw std::overflow_error("Iterator overflow");
2375  next_ne();
2376  }
2377 };
2378 
2401 template <class Node, class Op>
2402 bool prefix_traverse(Node * root, Op op) noexcept(noexcept(op))
2403 {
2404  for (BinNodePrefixIterator<Node> it(root); it.has_curr(); it.next_ne())
2405  if (not op(it.get_curr_ne()))
2406  return false;
2407  return true;
2408 }
2409 
2410 
2429 template <class Node, class Op>
2430 void prefix_for_each(Node * root, Op op) noexcept(noexcept(op))
2431 {
2432  for (BinNodePrefixIterator<Node> it(root); it.has_curr(); it.next_ne())
2433  op(it.get_curr_ne());
2434 }
2435 
2436 
2444 template <class Node>
2446 {
2447  mutable Node * root = Node::NullPtr;
2448  Node * curr = Node::NullPtr;
2449  long pos = 0;
2451 
2452  Node * advance_to_min(Node * r) noexcept
2453  {
2454  while (LLINK(r) != Node::NullPtr)
2455  {
2456  s.push(r);
2457  r = LLINK(r);
2458  }
2459  return r;
2460  }
2461 
2462  static Node * advance_to_max(Node * r) noexcept
2463  {
2464  while (RLINK(r) != Node::NullPtr)
2465  r = RLINK(r);
2466 
2467  return r;
2468  }
2469 
2470  void init() noexcept
2471  {
2472  if (root != Node::NullPtr)
2473  curr = advance_to_min(root);
2474  pos = 0;
2475  }
2476 
2477 public:
2478 
2479  void swap(BinNodeInfixIterator & it)
2480  {
2481  std::swap(root, it.root);
2482  std::swap(curr, it.curr);
2483  std::swap(pos, it.pos);
2484  s.swap(it.s);
2485  }
2486 
2487  BinNodeInfixIterator() noexcept { /* empty */ }
2488 
2490  BinNodeInfixIterator(Node * __root) noexcept
2491  : root(__root), s(Node::MaxHeight)
2492  {
2493  init();
2494  }
2495 
2497  : root(it.root), curr(it.curr), pos(it.pos), s(it.s)
2498  {
2499  // empty
2500  }
2501 
2502  BinNodeInfixIterator(BinNodeInfixIterator && it) { swap(it); }
2503 
2505  void reset_first() noexcept
2506  {
2507  s.empty();
2508  init();
2509  }
2510 
2512  void reset_last() noexcept
2513  {
2514  s.empty();
2515  curr = advance_to_max(root);
2516  pos = -2;
2517  }
2518 
2519  void end() noexcept
2520  {
2521  s.empty();
2522  curr = Node::NullPtr;
2523  pos = -1;
2524  }
2525 
2526  BinNodeInfixIterator & operator = (const BinNodeInfixIterator & it)
2527  {
2528  if (this == &it)
2529  return *this;
2530 
2531  root = it.root;
2532  curr = it.curr;
2533  pos = it.pos;
2534  s = it.s;
2535  return *this;
2536  }
2537 
2538  BinNodeInfixIterator & operator = (BinNodeInfixIterator && it)
2539  {
2540  swap(it);
2541  return *this;
2542  }
2543 
2545  bool has_curr() const noexcept { return curr != Node::NullPtr; }
2546 
2547  bool is_last() const noexcept
2548  {
2549  return curr != nullptr and RLINK(curr) == nullptr and s.is_empty();
2550  }
2551 
2553  Node * get_curr_ne() const noexcept { return curr; }
2554 
2556  Node * get_curr() const
2557  {
2558  if (not has_curr())
2559  throw std::overflow_error("Iterator overflow");
2560  return curr;
2561  }
2562 
2564  size_t get_pos() const { return pos; }
2565 
2566  void next_ne() noexcept
2567  {
2568  ++pos;
2569  curr = RLINK(curr);
2570  if (curr != Node::NullPtr)
2571  {
2572  curr = advance_to_min(curr);
2573  return;
2574  }
2575 
2576  if (s.is_empty())
2577  curr = Node::NullPtr;
2578  else
2579  curr = s.pop();
2580  }
2581 
2584  void next()
2585  {
2586  if (not has_curr())
2587  throw std::overflow_error("Iterator overflow");
2588  next_ne();
2589  }
2590 };
2591 
2614 template <class Node, class Op>
2615 bool infix_traverse(Node * root, Op op) noexcept(noexcept(op))
2616 {
2617  for (BinNodeInfixIterator<Node> it(root); it.has_curr(); it.next_ne())
2618  if (not op(it.get_curr_ne()))
2619  return false;
2620  return true;
2621 }
2622 
2627 template <class Node, class Op>
2628 bool traverse(Node * root, Op op) noexcept(noexcept(op))
2629 {
2630  return infix_traverse(root, op);
2631 }
2632 
2651 template <class Node, class Op>
2652 void infix_for_each(Node * root, Op op) noexcept(noexcept(op))
2653 {
2654  for (BinNodeInfixIterator<Node> it(root); it.has_curr(); it.next_ne())
2655  op(it.get_curr_ne());
2656 }
2657 
2658 } // end Aleph
2659 
2660 # endif // TPL_BINNODEUTILS_H
bool is_empty() const noexcept
Retrun true if stack is empty.
Definition: tpl_arrayStack.H:225
DynDlist< Node * > compute_nodes_in_level(Node *root, const int &level)
Definition: tpl_binNodeUtils.H:790
Definition: tpl_binNodeUtils.H:2445
Node * get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
Definition: tpl_binNodeUtils.H:2553
int read_bit(const size_t i) const
Definition: bitArray.H:280
void end() noexcept
Put the iterator in end state.
Definition: tpl_binNodeUtils.H:2308
Node * get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
Definition: tpl_binNodeUtils.H:2335
Definition: Queue.H:44
void swap_node_with_successor(Node *p, Node *&pp, Node *q, Node *&pq) noexcept
Definition: tpl_binNodeUtils.H:2048
DynList< Node * > infix(Node *root)
Definition: tpl_binNodeUtils.H:428
size_t compute_cardinality_rec(Node *root) noexcept
Definition: tpl_binNodeUtils.H:458
Definition: tpl_binNodeUtils.H:322
void split_key(Node *&root, const Key &key, Node *&l, Node *&r, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1984
size_t computeHeightRec(Node *root) noexcept
Definition: tpl_binNodeUtils.H:480
Node * insert_root(Node *&root, Node *p, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1773
void for_each_in_order(Node *root, Op &&op) noexcept(noexcept(op))
Definition: tpl_binNodeUtils.H:235
BinNodeInfixIterator(Node *__root) noexcept
Initialize an iterator on the first node inorder sense.
Definition: tpl_binNodeUtils.H:2490
void preOrderThreaded(Node *node, void(*visitFct)(Node *))
Definition: tpl_binNodeUtils.H:877
DynList< Node * > suffix(Node *root)
Definition: tpl_binNodeUtils.H:443
size_t internal_path_length(Node *p) noexcept
Definition: tpl_binNodeUtils.H:931
bool check_bst(Node *p, Compare cmp=Compare())
Definition: tpl_binNodeUtils.H:1262
void reset_last() noexcept
Reset the iterator to the first node inorder sense.
Definition: tpl_binNodeUtils.H:2512
Node * find_min(Node *root) noexcept
Definition: tpl_binNodeUtils.H:1346
Definition: bitArray.H:135
bool is_empty() const noexcept
rioReturn true if this is empty
Definition: tpl_dynListQueue.H:112
Definition: tpl_dynDlist.H:51
Definition: tpl_arrayStack.H:64
BinNodePrefixIterator(Node *__root) noexcept
Definition: tpl_binNodeUtils.H:2260
Node * rotate_to_left(Node *p, Node *pp) noexcept
Definition: tpl_binNodeUtils.H:1949
void save_tree(Node *root, ostream &output)
Definition: tpl_binNodeUtils.H:1101
void levelOrder(Node *root, void(*visitFct)(Node *, int, bool))
Definition: tpl_binNodeUtils.H:622
size_t size() const noexcept
Retorna la dimensión del arreglo de bits.
Definition: bitArray.H:241
Node * find_predecessor(Node *p, Node *&pp) noexcept
Definition: tpl_binNodeUtils.H:1405
bool split_key_rec(Node *&root, const typename Node::key_type &key, Node *&ts, Node *&tg, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1643
Definition: tpl_binNodeUtils.H:2240
Node * search_or_insert_root_rec(Node *root, Node *p, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:2197
void next_ne() noexcept
Definition: tpl_binNodeUtils.H:2347
Definition: tpl_dynListQueue.H:50
void next()
Definition: tpl_binNodeUtils.H:2584
Node * join_preorder(Node *t1, Node *t2, Node *&dup, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1821
Node * search_or_insert_in_bst(Node *&r, Node *p, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1577
T & push(const T &data)
Definition: tpl_arrayStack.H:118
Node * searchInBinTree(Node *root, const typename Node::key_type &key, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1323
Node::Key_Type & KEY(Node *p) noexcept
Definition: tpl_binNode.H:318
int preOrderRec(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_binNodeUtils.H:124
Definition: tpl_binNodeUtils.H:256
bool has_curr() const noexcept
Return true the iterator has current node.
Definition: tpl_binNodeUtils.H:2545
void load(std::istream &input)
Definition: bitArray.H:471
Definition: ah-comb.H:35
void load_tree_keys_in_prefix(Node *root, istream &input)
Definition: tpl_binNodeUtils.H:1074
void traverse(Node *root, Op &op) const noexcept(noexcept(op))
Invoke to traversal from root node.
Definition: tpl_binNodeUtils.H:208
Node * get_curr() const
Return a pointer to current node.
Definition: tpl_binNodeUtils.H:2338
void push(const unsigned int value)
Inserta al final del arreglo el valor value.
Definition: bitArray.H:347
void swap_node_with_predecessor(Node *p, Node *&pp, Node *q, Node *&pq) noexcept
Definition: tpl_binNodeUtils.H:2101
Node * insert_dup_in_bst(Node *&root, Node *p, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1549
void load_from_array_of_chars(const unsigned char str[], const size_t num_bits)
Definition: bitArray.H:545
Node *& LLINK(Node *p) noexcept
Definition: tpl_binNode.H:298
void swap(BinNodePrefixIterator &it)
Swap thiswith it
Definition: tpl_binNodeUtils.H:2249
void empty() noexcept
Empty the stack.
Definition: tpl_arrayStack.H:222
void save_tree_in_array_of_chars(Node *root, const string &array_name, ostream &output)
Definition: tpl_binNodeUtils.H:1195
int postOrderRec(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_binNodeUtils.H:168
void destroyRec(Node *&root) noexcept
Definition: tpl_binNodeUtils.H:500
bool level_traverse(Node *root, Operation &operation)
Definition: tpl_binNodeUtils.H:662
void save(std::ostream &output)
Definition: bitArray.H:443
void reset_last() noexcept
Reset the iterator to the last node in preorder.
Definition: tpl_binNodeUtils.H:2301
void operator()(Node *root, Op &op) const noexcept(noexcept(op))
Definition: tpl_binNodeUtils.H:215
Node * join(Node *t1, Node *t2, Node *&dup, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1855
void traverse(Node *root, Op &op) const noexcept(noexcept(op))
Invoke the traversal.
Definition: tpl_binNodeUtils.H:273
Definition: tpl_binNodeUtils.H:191
void save_tree_keys_in_prefix(Node *root, ostream &output)
Definition: tpl_binNodeUtils.H:1053
void save_in_array_of_chars(const string &name, std::ostream &output)
Definition: bitArray.H:508
BitArray tree_to_bits(Node *root)
Definition: tpl_binNodeUtils.H:977
Node * find_successor(Node *p, Node *&pp) noexcept
Definition: tpl_binNodeUtils.H:1380
Node * load_tree(istream &input)
Definition: tpl_binNodeUtils.H:1122
Node< Key > * build_tree(const DynArray< Key > &preorder, long l_p, long r_p, const DynArray< Key > &inorder, long l_i, long r_i)
Definition: tpl_binNodeUtils.H:706
void for_each_preorder(Node *root, Op &&op)
Definition: tpl_binNodeUtils.H:300
Node * find_max(Node *root) noexcept
Definition: tpl_binNodeUtils.H:1363
T pop()
Definition: tpl_arrayStack.H:167
Node * search_parent(Node *root, const typename Node::key_type &key, Node *&parent, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1436
void next()
Move the iterator one position forward.
Definition: tpl_binNodeUtils.H:2371
Node * rotate_to_right(Node *p, Node *pp) noexcept
Definition: tpl_binNodeUtils.H:1908
Node * insert_dup_root(Node *&root, Node *p, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1799
bool has_curr() const noexcept
Return true if iterator has current node.
Definition: tpl_binNodeUtils.H:2332
void traverse(Node *root, Op &op) const noexcept(noexcept(op))
Invoke the traversal.
Definition: tpl_binNodeUtils.H:339
Node * load_tree_from_array(const unsigned char bits[], const size_t &num_bits, const char *keys[])
Definition: tpl_binNodeUtils.H:1238
Node * join_exclusive(Node *&ts, Node *&tg) noexcept
Definition: tpl_binNodeUtils.H:1708
Node * preorder_to_bst(DynArray< typename Node::key_type > &preorder, int l, int r)
Definition: tpl_binNodeUtils.H:1292
Node * insert_in_bst(Node *&r, Node *p, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1522
Definition: ahDry.H:41
void split_key_dup_rec(Node *&root, const typename Node::key_type &key, Node *&ts, Node *&tg, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1686
size_t get_pos() const
Return the current position of iterator. Only valid if has_curr() == true.
Definition: tpl_binNodeUtils.H:2564
Node * copyRec(Node *root)
Definition: tpl_binNodeUtils.H:519
void for_each_postorder(Node *root, Op &&op)
Definition: tpl_binNodeUtils.H:366
bool infix_traverse(Node *root, Op op) noexcept(noexcept(op))
Definition: tpl_binNodeUtils.H:2615
Node * insert_root_rec(Node *root, Node *p, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:2158
T & append(const T &item)
Definition: htlist.H:1471
T get()
Definition: tpl_dynListQueue.H:165
Node * search_rank_parent(Node *root, const typename Node::key_type &key, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1484
DynList< Node * > prefix(Node *root)
Definition: tpl_binNodeUtils.H:413
Node *& RLINK(Node *p) noexcept
Definition: tpl_binNode.H:307
Node * bits_to_tree(const BitArray &array, int idx=0)
Definition: tpl_binNodeUtils.H:1030
void reset_first() noexcept
Reset the iterator to the first node in preorder sense.
Definition: tpl_binNodeUtils.H:2278
Definition: List.H:49
bool prefix_traverse(Node *root, Op op) noexcept(noexcept(op))
Definition: tpl_binNodeUtils.H:2402
Node * get_curr() const
Return the current node. Throw overflow_error if there is no current.
Definition: tpl_binNodeUtils.H:2556
Node * remove_from_bst(Node *&root, const typename Node::key_type &key, Compare cmp=Compare()) noexcept
Definition: tpl_binNodeUtils.H:1738
T & put(const T &data)
The type of element.
Definition: tpl_dynListQueue.H:125
T & append(const T &item)
Definition: tpl_dynDlist.H:149
int inOrderRec(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_binNodeUtils.H:80
void inOrderThreaded(Node *root, void(*visitFct)(Node *))
Definition: tpl_binNodeUtils.H:819
void swap(ArrayStack &s) noexcept
Swap this with s
Definition: tpl_arrayStack.H:100
void reset_first() noexcept
Reset the iterator to the first node inorder sense.
Definition: tpl_binNodeUtils.H:2505

Leandro Rabindranath León