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_tree_node.H
1 
2 # ifndef TPL_TREE_H
3 # define TPL_TREE_H
4 
5 # include <stdexcept>
6 # include <dlink.H>
7 # include <ahFunction.H>
8 # include <htlist.H>
9 # include <tpl_binNode.H>
10 
11 # define ISROOT(p) ((p)->is_root())
12 # define ISLEAF(p) ((p)->is_leaf())
13 # define ISLEFTMOST(p) ((p)->is_leftmost())
14 # define ISRIGHTMOST(p) ((p)->is_rightmost())
15 
16 # define SIBLING_LIST(p) ((p)->get_sibling_list())
17 # define CHILD_LIST(p) ((p)->get_child_list())
18 # define LCHILD(p) ((p)->get_left_child())
19 # define RSIBLING(p) ((p)->get_right_sibling())
20 # define IS_UNIQUE_SIBLING(p) (RSIBLING(p) == (p))
21 
22 namespace Aleph
23 {
24 
34  template <class T>
35 class Tree_Node
36 {
37  T data;
38  Dlink child;
39  Dlink sibling;
40  struct Flags
41  {
42  unsigned int is_root : 1;
43  unsigned int is_leaf : 1;
44  unsigned int is_leftmost : 1;
45  unsigned int is_rightmost : 1;
46  Flags() : is_root(1), is_leaf(1), is_leftmost(1), is_rightmost(1) {}
47  };
48 
49  Flags flags;
50  LINKNAME_TO_TYPE(Tree_Node, child);
51  LINKNAME_TO_TYPE(Tree_Node, sibling);
52 
53  Tree_Node * upper_link()
54  {
55  return child_to_Tree_Node(child.get_prev());
56  }
57 
58  Tree_Node * lower_link()
59  {
60  return child_to_Tree_Node(child.get_next());
61  }
62 
63  Tree_Node * left_link()
64  {
65  return sibling_to_Tree_Node(sibling.get_prev());
66  }
67 
68  Tree_Node * right_link()
69  {
70  return sibling_to_Tree_Node(sibling.get_next());
71  }
72 
73 public:
74 
76  T & get_key() { return get_data(); }
77 
79  T & get_data() { return data; }
80 
82  typedef T key_type;
83 
84  Dlink * get_child_list() { return &child; }
85 
86  Dlink * get_sibling_list() { return &sibling; }
87 
89  bool is_root() const { return flags.is_root; }
90 
92  bool is_leaf() const { return flags.is_leaf; }
93 
95  bool is_leftmost() const { return flags.is_leftmost; }
96 
98  bool is_rightmost() const { return flags.is_rightmost; }
99 
100  void set_is_root(bool value) { flags.is_root = value; }
101 
102  void set_is_leaf(bool value) { flags.is_leaf = value; }
103 
104  void set_is_leftmost(bool value) { flags.is_leftmost = value; }
105 
106  void set_is_rightmost(bool value) { flags.is_rightmost = value; }
107 
109  Tree_Node() { /* empty */ }
110 
112  Tree_Node(const T & __data) : data(__data) { /* empty */ }
113 
116  {
117  if (is_leftmost())
118  return NULL;
119 
120  return left_link();
121  }
122 
125  {
126  if (is_rightmost())
127  return NULL;
128 
129  return right_link();
130  }
131 
134  {
135  if (is_leaf())
136  return NULL;
137 
138  return lower_link();
139  }
140 
143  {
144  if (is_leaf())
145  return NULL;
146 
147  Tree_Node * left_child = lower_link();
148 
149  I(ISLEFTMOST(left_child));
150 
151  return left_child->left_link();
152  }
153 
161  Tree_Node * get_child(const int & i)
162  {
163  Tree_Node * c = get_left_child();
164 
165  for (int j = 1; c != NULL and j < i; ++j)
166  c = c->get_right_sibling();
167 
168  return c;
169  }
170 
173  {
174  if (is_root())
175  return NULL;
176 
177  Tree_Node * p = this;
178  while (not ISLEFTMOST(p)) // baje hasta el nodo más a la izquierda
179  p = p->left_link();
180 
181  I(not ISROOT(p));
182  I(not CHILD_LIST(p)->is_empty());
183 
184  return p->upper_link();
185  }
186 
194  {
195  if (p == NULL)
196  return;
197 
198  I(CHILD_LIST(p)->is_empty());
199  I(SIBLING_LIST(p)->is_empty());
200  I(p->is_rightmost() and p->is_leftmost() and p->is_root() and p->is_leaf());
201 
202  p->set_is_root(false);
203  p->set_is_leftmost(false);
204 
205  Tree_Node * old_next_node = get_right_sibling();
206  if (old_next_node != NULL)
207  {
208  I(not this->is_rightmost());
209  p->set_is_rightmost(false);
210  }
211  else
212  {
213  I(this->is_rightmost());
214  p->set_is_rightmost(true);
215  }
216 
217  this->set_is_rightmost(false);
218  this->sibling.insert(SIBLING_LIST(p));
219  }
220 
228  {
229  if (p == NULL)
230  return;
231 
232  if (this->is_root())
233  throw std::domain_error("Cannot insert sibling of a root");
234 
235  I(CHILD_LIST(p)->is_empty());
236  I(SIBLING_LIST(p)->is_empty());
237  I(p->is_rightmost() and p->is_leftmost() and p->is_root() and p->is_leaf());
238 
239  p->set_is_root(false);
240  p->set_is_rightmost(false);
241 
242  Tree_Node * old_prev_node = this->get_left_sibling();
243  if (old_prev_node != NULL)
244  {
245  I(not this->is_leftmost());
246  p->set_is_leftmost(false);
247  }
248  else
249  { // this es más a la izq ==> p debe a ser primogénito
250  I(this->is_leftmost());
251 
252  Tree_Node * parent = this->get_parent();
253 
254  ID(Tree_Node * left_child = this->get_left_child());
255  I(parent != NULL or left_child != NULL);
256 
257  // Busca la raíz del árbol. Para ello buscamnos la hoja de this
258  Tree_Node * leaf = this;
259  while (not leaf->is_leaf())
260  {
261  leaf = leaf->get_left_child();
262  I(leaf != NULL);
263  }
264 
265  Tree_Node * root = leaf->lower_link();
266  I(root != NULL);
267 
268  Dlink tree = CHILD_LIST(root)->cut_list(CHILD_LIST(this));
269  tree.del();
270  CHILD_LIST(parent)->insert(CHILD_LIST(p));
271  p->set_is_leftmost(true);
272 
273  I(p->get_parent() == parent);
274  }
275 
276  this->set_is_leftmost(false);
277  this->sibling.append(SIBLING_LIST(p));
278  }
279 
287  {
288  if (p == NULL)
289  return;
290 
291  I(CHILD_LIST(p)->is_empty());
292  I(SIBLING_LIST(p)->is_empty());
293  I(p->is_rightmost() and p->is_leftmost() and p->is_root() and p->is_leaf());
294 
295  p->set_is_root(false);
296  if (this->is_leaf())
297  {
298  this->set_is_leaf(false);
299  CHILD_LIST(this)->insert(CHILD_LIST(p));
300  }
301  else
302  {
303  Tree_Node * old_left_child = this->lower_link();
304  Tree_Node * leaf = old_left_child;
305  while (not leaf->is_leaf())
306  leaf = leaf->get_left_child();
307 
308  Tree_Node * root = leaf->lower_link();
309  Dlink subtree = CHILD_LIST(root)->cut_list(CHILD_LIST(old_left_child));
310  subtree.del();
311  CHILD_LIST(this)->insert(CHILD_LIST(p));
312  SIBLING_LIST(old_left_child)->append(SIBLING_LIST(p));
313  old_left_child->set_is_leftmost(false);
314  p->set_is_rightmost(false);
315  I(p->get_right_sibling() == old_left_child);
316  I(old_left_child->get_left_sibling() == p);
317  }
318  I(p->is_leftmost());
319  }
320 
328  {
329  if (p == NULL)
330  return;
331 
332  I(CHILD_LIST(p)->is_empty());
333  I(SIBLING_LIST(p)->is_empty());
334  I(p->is_rightmost() and p->is_leftmost() and p->is_root() and p->is_leaf());
335 
336  p->set_is_root(false);
337 
338  if (this->is_leaf())
339  {
340  this->set_is_leaf(false);
341  CHILD_LIST(this)->insert(CHILD_LIST(p));
342  }
343  else
344  {
345  Tree_Node * old_right_child_node = this->lower_link()->left_link();
346  old_right_child_node->set_is_rightmost(false);
347  p->set_is_leftmost(false);
348  SIBLING_LIST(old_right_child_node)->insert(SIBLING_LIST(p));
349  }
350  }
351 
361  {
362  if (tree == NULL)
363  return;
364 
365  if (not this->is_root())
366  throw std::domain_error("\"this\" is not root");
367 
368  tree->set_is_leftmost(false);
369  Tree_Node * old_next_tree = this->get_right_tree();
370  if (old_next_tree != NULL)
371  {
372  I(not this->is_rightmost());
373  tree->set_is_rightmost(false);
374  }
375 
376  this->set_is_rightmost(false);
377  SIBLING_LIST(this)->insert(SIBLING_LIST(tree));
378  }
379 
382  {
383  if (is_leftmost())
384  return NULL;
385  I(not is_leftmost());
386  return left_link();
387  }
388 
391  {
392  if (is_rightmost())
393  return NULL;
394 
395  I(not is_rightmost());
396  return right_link();
397  }
398 
403  {
404  if (not is_leftmost())
405  throw std::range_error("\"this\" is not the leftmost tree in the forest");
406 
407  return left_link();
408  }
409 
412  template <typename Operation>
413  void for_each_child(Operation & op)
414  {
415  for (Tree_Node * child = get_left_child(); child != NULL;
416  child = child->get_right_sibling())
417  op(child);
418  }
419 
420  template <typename Operation>
421  void for_each_child(Operation && op = Operation())
422  {
423  for_each_child<Operation>(op);
424  }
425 
426  template <typename Operation>
427  void for_each_child(Operation & op) const
428  {
429  return const_cast<Tree_Node*>(this)->for_each_child(op);
430  }
431 
432  template <typename Operation>
433  void for_each_child(Operation && op = Operation()) const
434  {
435  return const_cast<Tree_Node*>(this)->for_each_child(op);
436  }
437 
439  template <template <typename> class Container = DynList>
440  Container<Tree_Node*> children_nodes() const
441  {
442  Container<Tree_Node*> ret_val;
443  this->for_each_child([&ret_val] (Tree_Node * p) { ret_val.append(p); });
444  return ret_val;
445  }
446 
448  template <template <typename> class Container = DynList>
449  Container<T> children() const
450  {
451  Container<T> ret_val;
452  this->for_each_child([&ret_val] (Tree_Node * p)
453  {
454  ret_val.append(p->get_key());
455  });
456  return ret_val;
457  }
458 };
459 
460  template <class Node> static inline
461 void __tree_preorder_traversal(Node * root, const int & level,
462  const int & child_index,
463  void (*visitFct)(Node *, int, int))
464 {
465  (*visitFct)(root, level, child_index);
466  Node * child = root->get_left_child();
467  for (int i = 0; child != NULL; ++i, child = child->get_right_sibling())
468  __tree_preorder_traversal(child, level + 1, i, visitFct);
469 }
470 
493  template <class Node> inline
494 void tree_preorder_traversal(Node * root, void (*visitFct)(Node *, int, int))
495 {
496 
497  if (not root->is_root())
498  throw std::domain_error("root is not root");
499 
500  __tree_preorder_traversal(root, 0, 0, visitFct);
501 }
502 
525  template <class Node> inline
526 void forest_preorder_traversal(Node * root, void (*visitFct)(Node *, int, int))
527 {
528 
529  if (not root->is_root())
530  throw std::domain_error("root is not root");
531 
532  for (/* nada */; root != NULL; root = root->get_right_tree())
533  {
534  I(root->is_root());
535  __tree_preorder_traversal(root, 0, 0, visitFct);
536  }
537 }
538 
539  template <class Node> static inline
540 void __tree_postorder_traversal(Node * node, const int & level,
541  const int & child_index,
542  void (*visitFct)(Node *, int, int))
543 {
544  Node * child = node->get_left_child();
545 
546  for (int i = 0; child not_eq NULL; i++, child = child->get_right_sibling())
547  __tree_postorder_traversal(child, level + 1, i, visitFct);
548 
549  (*visitFct)(node, level, child_index);
550 }
551 
573  template <class Node> inline
574 void tree_postorder_traversal(Node * root, void (*visitFct)(Node *, int, int))
575 {
576  __tree_postorder_traversal(root, 0, 0, visitFct);
577 }
578 
602  template <class Node> inline
603 void forest_postorder_traversal(Node * root, void (*visitFct)(Node *, int, int))
604 {
605  if (not root->is_leftmost())
606  throw std::domain_error("root is not the leftmost node of forest");
607 
608  if (not root->is_root())
609  throw std::domain_error("root is not root");
610 
611  for (/* nada */; root not_eq NULL; root = root->get_right_sibling())
612  {
613  I(root->is_root());
614  __tree_postorder_traversal(root, 0, 0, visitFct);
615  }
616 }
617 
626  template <class Node> inline
627 void destroy_tree(Node * root)
628 {
629  if (not IS_UNIQUE_SIBLING(root))
630  SIBLING_LIST(root)->del(); // no ==> sacarlo de lista hermanos
631 
632  // recorrer los subárboles de derecha a izquierda
633  for (Node * p = (Node*) root->get_right_child(); p != NULL; /* nada */)
634  {
635  Node * to_delete = p; // respaldar subárbol a borrar p
636  p = (Node*) p->get_left_sibling(); // Avanzar p a hermano izquierdo
637  destroy_tree(to_delete); // eliminar recursivamente árbol
638  }
639 
640  if (root->is_leftmost()) // ¿sacar lista hijos?
641  CHILD_LIST(root)->del();
642 
643  delete root;
644 }
645 
658  template <class Node> inline
659 void destroy_forest(Node * root)
660 {
661 
662  if (not root->is_leftmost())
663  throw std::domain_error("root is not the leftmost tree of forest");
664 
665  if (not root->is_root())
666  throw std::domain_error("root is not root");
667 
668  while (root != NULL) // recorre los árboles de izquierda a derecha
669  {
670  Node * to_delete = root; // respalda raíz
671  root = root->get_right_sibling(); // avanza a siguiente árbol
672  SIBLING_LIST(to_delete)->del(); // elimine de lista árboles
673  destroy_tree(to_delete); // Borre el árbol
674  }
675 }
676 
683  template <class Node>
684 size_t compute_height(Node * root)
685 {
686  size_t temp_h, max_h = 0;
687  for (Node * aux = root->get_left_child(); aux != NULL;
688  aux = aux->get_right_sibling())
689  if ((temp_h = compute_height(aux)) > max_h)
690  max_h = temp_h;
691 
692  return max_h + 1;
693 }
694 
695  template <class Node> static inline
696 Node * __deway_search(Node * node, int path [],
697  const int & idx, const size_t & size)
698 {
699  if (node == NULL)
700  return NULL;
701 
702  if (idx > size)
703  throw std::out_of_range("index out of maximum range");
704 
705  if (path[idx] < 0) // verifique si se ha alcanzado el nodo
706  return node;
707  // avance hasta el próximo hijo path[0]
708  Node * child = node->get_left_child();
709  for (int i = 0; i < path[idx] and child != NULL; ++i)
710  child = child->get_right_sibling();
711 
712  return __deway_search(child, path, idx + 1, size); // próximo nivel
713 }
714 
728  template <class Node> inline
729 Node * deway_search(Node * root, int path [], const size_t & size)
730 {
731  for (int i = 0; root != NULL; i++, root = root->get_right_sibling())
732  if (path[0] == i)
733  return __deway_search(root, path, 1, size);
734 
735  return NULL;
736 }
737 
738  template <class Node, class Equal> inline static
739 Node * __search_deway(Node * root, const typename Node::key_type & key,
740  const size_t & current_level, int deway [],
741  const size_t & size, size_t & n);
742 
765  template <class Node,
766  class Equal = Aleph::equal_to<typename Node::key_type> > inline
767 Node * search_deway(Node * root, const typename Node::key_type & key,
768  int deway [], const size_t & size, size_t & n)
769 {
770  n = 1; // valor inicial de longitud de número de Deway
771 
772  if (size < n)
773  throw std::overflow_error("there is no enough space for deway array");
774 
775  for (int i = 0; root != NULL; i++, root = root->get_right_sibling())
776  {
777  deway[0] = i;
778  Node * result =
779  __search_deway <Node, Equal> (root, key, 0, deway, size, n);
780  if (result != NULL)
781  return result;
782  }
783 
784  return NULL;
785 }
786 
787  template <class Node, class Equal> inline static
788 Node * __search_deway(Node * root,
789  const typename Node::key_type & key,
790  const size_t & current_level, int deway [],
791  const size_t & size, size_t & n)
792 {
793 
794  if (current_level >= size)
795  throw std::overflow_error("there is no enough space for deway array");
796 
797  if (root == NULL)
798  return NULL;
799 
800  if (Equal () (KEY(root), key))
801  {
802  n = current_level + 1; // longitud del arreglo deway
803  return root;
804  }
805 
806  Node * child = root->get_left_child();
807  for (int i = 0; child != NULL;
808  i++, child = child->get_right_sibling())
809  {
810  deway[current_level + 1] = i;
811  Node * result = __search_deway <Node, Equal>
812  (child, key, current_level + 1, deway, size, n);
813 
814  if (result!= NULL)
815  return result;
816  }
817 
818  return NULL;
819 }
820 
841  template <class TNode, class BNode>
842 BNode * forest_to_bin(TNode * root)
843 {
844  if (root == NULL)
845  return BNode::NullPtr;
846 
847  BNode * result = new BNode (root->get_key());
848  LLINK(result) = forest_to_bin<TNode,BNode>(root->get_left_child());
849  RLINK(result) = forest_to_bin<TNode,BNode>(root->get_right_sibling());
850 
851  return result;
852 }
853 
854  template <class TNode, class BNode> inline static
855 void insert_child(BNode * lnode, TNode * tree_node)
856 {
857  if (lnode == BNode::NullPtr)
858  return;
859 
860  TNode * child = new TNode(KEY(lnode));
861  tree_node->insert_leftmost_child(child);
862 }
863 
864  template <class TNode, class BNode> inline static
865 void insert_sibling(BNode * rnode, TNode * tree_node)
866 {
867  if (rnode == BNode::NullPtr)
868  return;
869 
870  TNode * sibling = new TNode(KEY(rnode));
871  tree_node->insert_right_sibling(sibling);
872 }
873 
874  template <class TNode, class BNode> inline static
875 void bin_to_tree(BNode * broot, TNode * troot)
876 {
877  if (broot == BNode::NullPtr)
878  return;
879 
880  insert_child(LLINK(broot), troot);
881  TNode * left_child = troot->get_left_child();
882 
883  bin_to_tree(LLINK(broot), left_child);
884 
885  insert_sibling(RLINK(broot), troot);
886  TNode * right_sibling = troot->get_right_sibling();
887 
888  bin_to_tree(RLINK(broot), right_sibling);
889 }
890 
910  template <class TNode, class BNode> inline
911 TNode * bin_to_forest(BNode * broot)
912 {
913  if (broot == BNode::NullPtr)
914  return NULL;
915 
916  TNode * troot = new TNode (KEY(broot));
917  bin_to_tree(broot, troot);
918  return troot;
919 }
920 
921 } // fin namespace Aleph
922 
923 # endif // TPL_TREE_H
924 
bool is_root() const
Retorna true si this es la raíz del árbol general.
Definition: tpl_tree_node.H:89
#define LLINK(p)
Definition: tpl_binNode.H:196
bool is_leaf() const
Retorna true si this es un nodo hoja.
Definition: tpl_tree_node.H:92
#define RLINK(p)
Definition: tpl_binNode.H:201
T & get_data()
retorna referencia modificable al contenido del nodo.
Definition: tpl_tree_node.H:79
void insert_right_sibling(Tree_Node *p)
Definition: tpl_tree_node.H:193
void insert_left_sibling(Tree_Node *p)
Definition: tpl_tree_node.H:227
Container< Tree_Node * > children_nodes() const
Retorna una lista de los nodos hijos de this.
Definition: tpl_tree_node.H:440
void tree_postorder_traversal(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_tree_node.H:574
Tree_Node * get_child(const int &i)
Definition: tpl_tree_node.H:161
Tree_Node * get_right_sibling()
Retorna hermano derecho de this.
Definition: tpl_tree_node.H:124
void destroy_tree(Node *root)
Definition: tpl_tree_node.H:627
Tree_Node()
Constructor vacío (clave indefinida).
Definition: tpl_tree_node.H:109
void insert_rightmost_child(Tree_Node *p)
Definition: tpl_tree_node.H:327
Tree_Node * get_right_tree()
Retorna el árbol a la derecha de this.
Definition: tpl_tree_node.H:390
BNode * forest_to_bin(TNode *root)
Definition: tpl_tree_node.H:842
Node * search_deway(Node *root, const typename Node::key_type &key, int deway[], const size_t &size, size_t &n)
Definition: tpl_tree_node.H:767
bool is_leftmost() const
Retorna true si this es el nodo más a la izquierda de sus hermanos.
Definition: tpl_tree_node.H:95
Definition: tpl_tree_node.H:35
Tree_Node(const T &__data)
Constructor con valor de dato __data.
Definition: tpl_tree_node.H:112
bool is_rightmost() const
Retorna true si this es el nodo más a la derecha de sus hermanos.
Definition: tpl_tree_node.H:98
void for_each_child(Operation &op)
Definition: tpl_tree_node.H:413
Node * deway_search(Node *root, int path[], const size_t &size)
Definition: tpl_tree_node.H:729
void insert_leftmost_child(Tree_Node *p)
Definition: tpl_tree_node.H:286
Tree_Node * get_last_tree()
Definition: tpl_tree_node.H:402
Tree_Node * get_left_tree()
Retorna el árbol a la izquierda de this.
Definition: tpl_tree_node.H:381
T key_type
Tipo de dato genérico que contiene el nodo.
Definition: tpl_tree_node.H:82
TNode * bin_to_forest(BNode *broot)
Definition: tpl_tree_node.H:911
Container< T > children() const
Retorna una lista de los contenidos de los hijos de this.
Definition: tpl_tree_node.H:449
T & get_key()
retorna referencia modificable al contenido del nodo.
Definition: tpl_tree_node.H:76
Tree_Node * get_left_child()
retorna el hijo más a la izquierda de this.
Definition: tpl_tree_node.H:133
void insert_tree_to_right(Tree_Node *tree)
Definition: tpl_tree_node.H:360
Tree_Node * get_parent()
Retorna el padre de this.
Definition: tpl_tree_node.H:172
Tree_Node * get_right_child()
retorna el hijo más a la derecha de this.
Definition: tpl_tree_node.H:142
Tree_Node * get_left_sibling()
Retorna hermano izquierdo de this.
Definition: tpl_tree_node.H:115
void forest_preorder_traversal(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_tree_node.H:526
Definition: ahDry.H:13
#define KEY(p)
Definition: tpl_binNode.H:206
Definition: ahFunction.H:115
void forest_postorder_traversal(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_tree_node.H:603
size_t compute_height(Node *root)
Definition: tpl_tree_node.H:684
void destroy_forest(Node *root)
Definition: tpl_tree_node.H:659
void tree_preorder_traversal(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_tree_node.H:494

Leandro Rabindranath León