7 # include <ahFunction.H>
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())
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))
55 return child_to_Tree_Node(child.
get_prev());
60 return child_to_Tree_Node(child.
get_next());
65 return sibling_to_Tree_Node(sibling.
get_prev());
70 return sibling_to_Tree_Node(sibling.
get_next());
84 Dlink * get_child_list() {
return &child; }
86 Dlink * get_sibling_list() {
return &sibling; }
89 bool is_root()
const {
return flags.is_root; }
92 bool is_leaf()
const {
return flags.is_leaf; }
100 void set_is_root(
bool value) { flags.is_root = value; }
102 void set_is_leaf(
bool value) { flags.is_leaf = value; }
104 void set_is_leftmost(
bool value) { flags.is_leftmost = value; }
106 void set_is_rightmost(
bool value) { flags.is_rightmost = value; }
149 I(ISLEFTMOST(left_child));
151 return left_child->left_link();
165 for (
int j = 1; c != NULL and j < i; ++j)
178 while (not ISLEFTMOST(p))
182 I(not CHILD_LIST(p)->is_empty());
184 return p->upper_link();
198 I(CHILD_LIST(p)->is_empty());
199 I(SIBLING_LIST(p)->is_empty());
202 p->set_is_root(
false);
203 p->set_is_leftmost(
false);
206 if (old_next_node != NULL)
209 p->set_is_rightmost(
false);
214 p->set_is_rightmost(
true);
217 this->set_is_rightmost(
false);
218 this->sibling.
insert(SIBLING_LIST(p));
233 throw std::domain_error(
"Cannot insert sibling of a root");
235 I(CHILD_LIST(p)->is_empty());
236 I(SIBLING_LIST(p)->is_empty());
239 p->set_is_root(
false);
240 p->set_is_rightmost(
false);
243 if (old_prev_node != NULL)
246 p->set_is_leftmost(
false);
255 I(parent != NULL or left_child != NULL);
268 Dlink tree = CHILD_LIST(root)->cut_list(CHILD_LIST(
this));
270 CHILD_LIST(parent)->insert(CHILD_LIST(p));
271 p->set_is_leftmost(
true);
276 this->set_is_leftmost(
false);
277 this->sibling.
append(SIBLING_LIST(p));
291 I(CHILD_LIST(p)->is_empty());
292 I(SIBLING_LIST(p)->is_empty());
295 p->set_is_root(
false);
298 this->set_is_leaf(
false);
299 CHILD_LIST(
this)->insert(CHILD_LIST(p));
303 Tree_Node * old_left_child = this->lower_link();
309 Dlink subtree = CHILD_LIST(root)->cut_list(CHILD_LIST(old_left_child));
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);
332 I(CHILD_LIST(p)->is_empty());
333 I(SIBLING_LIST(p)->is_empty());
336 p->set_is_root(
false);
340 this->set_is_leaf(
false);
341 CHILD_LIST(
this)->insert(CHILD_LIST(p));
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));
366 throw std::domain_error(
"\"this\" is not root");
368 tree->set_is_leftmost(
false);
370 if (old_next_tree != NULL)
373 tree->set_is_rightmost(
false);
376 this->set_is_rightmost(
false);
377 SIBLING_LIST(
this)->insert(SIBLING_LIST(tree));
405 throw std::range_error(
"\"this\" is not the leftmost tree in the forest");
412 template <
typename Operation>
416 child = child->get_right_sibling())
420 template <
typename Operation>
423 for_each_child<Operation>(op);
426 template <
typename Operation>
432 template <
typename Operation>
439 template <
template <
typename>
class Container =
DynList>
442 Container<Tree_Node*> ret_val;
448 template <
template <
typename>
class Container =
DynList>
451 Container<T> ret_val;
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))
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);
493 template <
class Node>
inline
497 if (not root->is_root())
498 throw std::domain_error(
"root is not root");
500 __tree_preorder_traversal(root, 0, 0, visitFct);
525 template <
class Node>
inline
529 if (not root->is_root())
530 throw std::domain_error(
"root is not root");
532 for (; root != NULL; root = root->get_right_tree())
535 __tree_preorder_traversal(root, 0, 0, visitFct);
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))
544 Node * child = node->get_left_child();
546 for (
int i = 0; child not_eq NULL; i++, child = child->get_right_sibling())
547 __tree_postorder_traversal(child, level + 1, i, visitFct);
549 (*visitFct)(node, level, child_index);
573 template <
class Node>
inline
576 __tree_postorder_traversal(root, 0, 0, visitFct);
602 template <
class Node>
inline
605 if (not root->is_leftmost())
606 throw std::domain_error(
"root is not the leftmost node of forest");
608 if (not root->is_root())
609 throw std::domain_error(
"root is not root");
611 for (; root not_eq NULL; root = root->get_right_sibling())
614 __tree_postorder_traversal(root, 0, 0, visitFct);
626 template <
class Node>
inline
629 if (not IS_UNIQUE_SIBLING(root))
630 SIBLING_LIST(root)->del();
633 for (Node * p = (Node*) root->get_right_child(); p != NULL; )
635 Node * to_delete = p;
636 p = (Node*) p->get_left_sibling();
640 if (root->is_leftmost())
641 CHILD_LIST(root)->del();
658 template <
class Node>
inline
662 if (not root->is_leftmost())
663 throw std::domain_error(
"root is not the leftmost tree of forest");
665 if (not root->is_root())
666 throw std::domain_error(
"root is not root");
670 Node * to_delete = root;
671 root = root->get_right_sibling();
672 SIBLING_LIST(to_delete)->del();
683 template <
class Node>
686 size_t temp_h, max_h = 0;
687 for (Node * aux = root->get_left_child(); aux != NULL;
688 aux = aux->get_right_sibling())
695 template <
class Node>
static inline
696 Node * __deway_search(Node * node,
int path [],
697 const int & idx,
const size_t & size)
703 throw std::out_of_range(
"index out of maximum range");
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();
712 return __deway_search(child, path, idx + 1, size);
728 template <
class Node>
inline
731 for (
int i = 0; root != NULL; i++, root = root->get_right_sibling())
733 return __deway_search(root, path, 1, size);
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);
765 template <
class Node,
768 int deway [],
const size_t & size,
size_t & n)
773 throw std::overflow_error(
"there is no enough space for deway array");
775 for (
int i = 0; root != NULL; i++, root = root->get_right_sibling())
779 __search_deway <Node, Equal> (root, key, 0, deway, size, n);
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)
794 if (current_level >= size)
795 throw std::overflow_error(
"there is no enough space for deway array");
800 if (Equal () (
KEY(root), key))
802 n = current_level + 1;
806 Node * child = root->get_left_child();
807 for (
int i = 0; child != NULL;
808 i++, child = child->get_right_sibling())
810 deway[current_level + 1] = i;
811 Node * result = __search_deway <Node, Equal>
812 (child, key, current_level + 1, deway, size, n);
841 template <
class TNode,
class BNode>
845 return BNode::NullPtr;
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());
854 template <
class TNode,
class BNode>
inline static
855 void insert_child(BNode * lnode, TNode * tree_node)
857 if (lnode == BNode::NullPtr)
860 TNode * child =
new TNode(
KEY(lnode));
861 tree_node->insert_leftmost_child(child);
864 template <
class TNode,
class BNode>
inline static
865 void insert_sibling(BNode * rnode, TNode * tree_node)
867 if (rnode == BNode::NullPtr)
870 TNode * sibling =
new TNode(
KEY(rnode));
871 tree_node->insert_right_sibling(sibling);
874 template <
class TNode,
class BNode>
inline static
875 void bin_to_tree(BNode * broot, TNode * troot)
877 if (broot == BNode::NullPtr)
880 insert_child(
LLINK(broot), troot);
881 TNode * left_child = troot->get_left_child();
883 bin_to_tree(
LLINK(broot), left_child);
885 insert_sibling(
RLINK(broot), troot);
886 TNode * right_sibling = troot->get_right_sibling();
888 bin_to_tree(
RLINK(broot), right_sibling);
910 template <
class TNode,
class BNode>
inline
913 if (broot == BNode::NullPtr)
916 TNode * troot =
new TNode (
KEY(broot));
917 bin_to_tree(broot, troot);
923 # endif // TPL_TREE_H
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
Dlink *& get_next()
Retorna enlace después de this.
Definition: dlink.H:179
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
Dlink *& get_prev()
Retorna enlace antes de this.
Definition: dlink.H:189
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
void append(Dlink *node)
Definition: dlink.H:166
#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 del()
Elimina this de su contexto en una lista.
Definition: dlink.H:278
void destroy_forest(Node *root)
Definition: tpl_tree_node.H:659
void insert(Dlink *node)
Definition: dlink.H:140
void tree_preorder_traversal(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_tree_node.H:494