34 # include <ahIterator.H> 35 # include <ahFunction.H> 36 # include <ahFunctional.H> 38 # include <tpl_dynListStack.H> 39 # include <tpl_dynListQueue.H> 40 # include <tpl_binNode.H> 42 # define ISROOT(p) ((p)->is_root()) 43 # define ISLEAF(p) ((p)->is_leaf()) 44 # define ISLEFTMOST(p) ((p)->is_leftmost()) 45 # define ISRIGHTMOST(p) ((p)->is_rightmost()) 47 # define SIBLING_LIST(p) ((p)->get_sibling_list()) 48 # define CHILD_LIST(p) ((p)->get_child_list()) 49 # define SIBLING_LINK(p) ((p)->get_sibling_list()) 50 # define LCHILD(p) ((p)->get_left_child()) 51 # define RSIBLING(p) ((p)->get_right_sibling()) 52 # define IS_UNIQUE_SIBLING(p) (RSIBLING(p) == (p)) 90 return child_to_Tree_Node(child.
get_prev());
95 return child_to_Tree_Node(child.
get_next());
100 return sibling_to_Tree_Node(sibling.
get_prev());
105 return sibling_to_Tree_Node(sibling.
get_next());
120 const T &
get_data()
const noexcept {
return data; }
125 Dlink * get_child_list() noexcept {
return &child; }
127 Dlink * get_sibling_list() noexcept {
return &sibling; }
130 bool is_root() const noexcept {
return flags.is_root; }
133 bool is_leaf() const noexcept {
return flags.is_leaf; }
141 void set_is_root(
bool value) noexcept { flags.is_root = value; }
143 void set_is_leaf(
bool value) noexcept { flags.is_leaf = value; }
145 void set_is_leftmost(
bool value) noexcept { flags.is_leftmost = value; }
147 void set_is_rightmost(
bool value) noexcept { flags.is_rightmost = value; }
154 noexcept(std::is_nothrow_copy_constructible<T>::value)
158 noexcept(std::is_nothrow_move_constructible<T>::value)
159 : data(std::move(__data)) { }
196 assert(ISLEFTMOST(left_child));
198 return left_child->left_link();
211 for (
int j = 0; c !=
nullptr and j < i; ++j)
224 while (not ISLEFTMOST(p))
227 assert(not ISROOT(p));
228 assert(not CHILD_LIST(p)->is_empty());
230 return p->upper_link();
244 assert(CHILD_LIST(p)->is_empty());
245 assert(SIBLING_LIST(p)->is_empty());
246 assert(p->is_rightmost() and p->is_leftmost() and p->is_root() and
249 p->set_is_root(
false);
250 p->set_is_leftmost(
false);
253 if (old_next_node !=
nullptr)
256 p->set_is_rightmost(
false);
261 p->set_is_rightmost(
true);
264 this->set_is_rightmost(
false);
265 this->sibling.
insert(SIBLING_LIST(p));
280 throw std::domain_error(
"Cannot insert sibling of a root");
282 assert(CHILD_LIST(p)->is_empty());
283 assert(SIBLING_LIST(p)->is_empty());
287 p->set_is_root(
false);
288 p->set_is_rightmost(
false);
291 if (old_prev_node !=
nullptr)
294 p->set_is_leftmost(
false);
307 assert(leaf !=
nullptr);
311 assert(root !=
nullptr);
313 Dlink tree = CHILD_LIST(root)->cut_list(CHILD_LIST(
this));
315 CHILD_LIST(parent)->insert(CHILD_LIST(p));
316 p->set_is_leftmost(
true);
321 this->set_is_leftmost(
false);
322 this->sibling.
append(SIBLING_LIST(p));
336 assert(CHILD_LIST(p)->is_empty());
337 assert(SIBLING_LIST(p)->is_empty());
338 assert(p->is_rightmost() and p->is_leftmost() and p->is_root() and
341 p->set_is_root(
false);
344 this->set_is_leaf(
false);
345 CHILD_LIST(
this)->insert(CHILD_LIST(p));
349 Tree_Node * old_left_child = this->lower_link();
355 Dlink subtree = CHILD_LIST(root)->cut_list(CHILD_LIST(old_left_child));
357 CHILD_LIST(
this)->insert(CHILD_LIST(p));
358 SIBLING_LIST(old_left_child)->append(SIBLING_LIST(p));
359 old_left_child->set_is_leftmost(
false);
360 p->set_is_rightmost(
false);
361 assert(p->get_right_sibling() == old_left_child);
364 assert(p->is_leftmost());
378 assert(CHILD_LIST(p)->is_empty());
379 assert(SIBLING_LIST(p)->is_empty());
380 assert(p->is_rightmost() and p->is_leftmost() and p->is_root() and
383 p->set_is_root(
false);
387 this->set_is_leaf(
false);
388 CHILD_LIST(
this)->insert(CHILD_LIST(p));
392 Tree_Node * old_right_child_node = this->lower_link()->left_link();
393 old_right_child_node->set_is_rightmost(
false);
394 p->set_is_leftmost(
false);
395 SIBLING_LIST(old_right_child_node)->insert(SIBLING_LIST(p));
403 assert(tree !=
nullptr);
406 tree->set_is_root(
false);
410 assert(CHILD_LIST(
this)->is_empty() and SIBLING_LIST(
this)->is_empty());
411 this->set_is_leaf(
false);
412 CHILD_LIST(
this)->splice(CHILD_LIST(tree));
416 Tree_Node * right_child = this->lower_link()->left_link();
417 right_child->set_is_rightmost(
false);
418 tree->set_is_leftmost(
false);
419 SIBLING_LINK(right_child)->splice(SIBLING_LINK(tree));
443 throw std::domain_error(
"\"this\" is not root");
445 tree->set_is_leftmost(
false);
447 if (old_next_tree !=
nullptr)
450 tree->set_is_rightmost(
false);
453 this->set_is_rightmost(
false);
454 SIBLING_LIST(
this)->insert(SIBLING_LIST(tree));
482 throw std::range_error(
"\"this\" is not the leftmost tree in the forest");
488 template <
template <
typename>
class Container =
DynList>
491 Container<Tree_Node*> ret;
492 for (
auto t = const_cast<Tree_Node*>(
this); t !=
nullptr;
493 t = t->get_right_tree())
500 template <
typename Operation>
504 child = child->get_right_sibling())
508 template <
typename Operation>
511 for_each_child<Operation>(op);
515 template <
template <
typename>
class Container =
DynList>
518 Container<Tree_Node*> ret_val;
524 template <
template <
typename>
class Container =
DynList>
527 Container<T> ret_val;
537 template <
class Operation>
static 538 bool preorder(
const Tree_Node * root, Operation & op)
547 child = child->get_right_sibling())
548 if (not preorder(child, op))
557 template <
class Operation>
560 return preorder(
this, op);
563 template <
class Operation>
609 : curr(const_cast<Children_Iterator&>(it).curr) {}
611 bool has_curr()
const noexcept {
return curr !=
nullptr; }
613 Tree_Node * get_curr_ne()
const noexcept {
return curr; }
618 throw std::overflow_error(
"Children_Iterator::get_curr()");
619 return get_curr_ne();
622 void next_ne() noexcept { curr = curr->get_right_sibling(); }
627 throw std::overflow_error(
"Children_Iterator::next()");
643 using Children_Iterator::Children_Iterator;
658 void swap(Iterator & it)
660 std::swap(root, it.root);
661 std::swap(curr, it.curr);
662 std::swap(pos, it.pos);
666 Iterator(
Tree_Node * __root =
nullptr) noexcept
667 : root(__root), curr(root)
672 Iterator(
Tree_Node & root) : Iterator(&root) {}
674 Iterator(
const Iterator & it)
675 : root(it.root), curr(it.curr), pos(it.pos), s(it.s)
680 Iterator(Iterator && it) { swap(it); }
682 Iterator & operator = (
const Iterator & it)
694 Iterator & operator = (Iterator && it)
700 void reset_first() noexcept
706 bool has_curr()
const noexcept {
return curr !=
nullptr; }
708 Tree_Node * get_curr_ne()
const noexcept {
return curr; }
713 throw std::overflow_error(
"Iterator overflow");
714 return get_curr_ne();
717 void next_ne() noexcept
721 if (lchild ==
nullptr)
741 throw std::overflow_error(
"Iterator overflow");
754 size_t get_pos()
const {
return pos; }
757 Iterator get_it()
const 759 return Iterator(const_cast<Tree_Node*>(
this));
765 template <
typename T>
766 struct Tree_Node_Vtl :
public Tree_Node<T>
768 virtual ~Tree_Node_Vtl() {}
771 template <
class Node>
static inline 772 void clone_tree(Node * src, Node * tgt)
774 using It =
typename Node::Children_Iterator;
775 for (It it(src); it.has_curr(); it.next_ne())
776 tgt->insert_rightmost_child(
new Node(it.get_curr_ne()->get_key()));
778 using PItor = Pair_Iterator<It>;
779 for (PItor itor{It(*src), It(*tgt)}; itor.has_curr(); itor.next_ne())
781 auto p = itor.get_curr_ne();
782 clone_tree(p.first, p.second);
786 template <
class Node>
787 Node * clone_tree(Node * root)
791 Node * ret =
new Node(root->get_key());
792 clone_tree(root, ret);
796 template <
class Node>
static inline 797 void __tree_preorder_traversal(Node * root,
const int & level,
798 const int & child_index,
799 void (*visitFct)(Node *,
int,
int))
801 (*visitFct)(root, level, child_index);
802 Node * child = root->get_left_child();
803 for (
int i = 0; child !=
nullptr; ++i, child = child->get_right_sibling())
804 __tree_preorder_traversal(child, level + 1, i, visitFct);
829 template <
class Node>
inline 833 if (not root->is_root())
834 throw std::domain_error(
"root is not root");
836 __tree_preorder_traversal(root, 0, 0, visitFct);
861 template <
class Node>
inline 864 if (not root->is_root())
865 throw std::domain_error(
"root is not root");
867 for (; root !=
nullptr; root = root->get_right_tree())
869 assert(root->is_root());
870 __tree_preorder_traversal(root, 0, 0, visitFct);
874 template <
class Node>
static inline 875 void __tree_postorder_traversal(Node * node,
const int & level,
876 const int & child_index,
877 void (*visitFct)(Node *,
int,
int))
879 Node * child = node->get_left_child();
881 for (
int i = 0; child not_eq
nullptr; i++, child = child->get_right_sibling())
882 __tree_postorder_traversal(child, level + 1, i, visitFct);
884 (*visitFct)(node, level, child_index);
908 template <
class Node>
inline 911 __tree_postorder_traversal(root, 0, 0, visitFct);
937 template <
class Node>
inline 940 if (not root->is_leftmost())
941 throw std::domain_error(
"root is not the leftmost node of forest");
943 if (not root->is_root())
944 throw std::domain_error(
"root is not root");
946 for (; root not_eq
nullptr; root = root->get_right_sibling())
948 assert(root->is_root());
949 __tree_postorder_traversal(root, 0, 0, visitFct);
957 template <
class Node,
class Eq>
959 noexcept(noexcept(eq(t1->get_key(), t2->get_key())))
962 return t2 ==
nullptr;
967 if (not eq(t1->get_key(), t2->get_key()))
972 return zipEq(t1->children_nodes(), t2->children_nodes()).all([] (
auto p)
977 catch (std::length_error)
983 template <
class Node,
984 class Eq = std::equal_to<typename Node::key_type>>
986 noexcept(noexcept(are_tree_equal<Node, Eq>(t1, t2, eq)))
988 return are_tree_equal<Node, Eq>(t1, t2, eq);
999 template <
class Node>
inline 1002 if (root ==
nullptr)
1005 if (not IS_UNIQUE_SIBLING(root))
1006 SIBLING_LIST(root)->del();
1009 for (Node * p = (Node*) root->get_right_child(); p !=
nullptr; )
1011 Node * to_delete = p;
1012 p = (Node*) p->get_left_sibling();
1016 if (root->is_leftmost())
1017 CHILD_LIST(root)->del();
1034 template <
class Node>
inline 1037 if (root ==
nullptr)
1040 if (not root->is_leftmost())
1041 throw std::domain_error(
"root is not the leftmost tree of forest");
1043 if (not root->is_root())
1044 throw std::domain_error(
"root is not root");
1046 while (root !=
nullptr)
1048 Node * to_delete = root;
1049 root = root->get_right_sibling();
1050 SIBLING_LIST(to_delete)->del();
1061 template <
class Node>
1064 if (root ==
nullptr)
1067 size_t temp_h, max_h = 0;
1068 for (Node * aux = root->get_left_child(); aux !=
nullptr;
1069 aux = aux->get_right_sibling())
1076 template <
class Node>
static inline 1077 Node * __deway_search(Node * node,
int path [],
1078 const int & idx,
const size_t & size)
1080 if (node ==
nullptr)
1084 throw std::out_of_range(
"index out of maximum range");
1089 Node * child = node->get_left_child();
1090 for (
int i = 0; i < path[idx] and child !=
nullptr; ++i)
1091 child = child->get_right_sibling();
1093 return __deway_search(child, path, idx + 1, size);
1109 template <
class Node>
inline 1112 for (
int i = 0; root !=
nullptr; i++, root = root->get_right_sibling())
1114 return __deway_search(root, path, 1, size);
1119 template <
class Node,
class Equal>
inline static 1120 Node * __search_deway(Node * root,
const typename Node::key_type & key,
1121 const size_t & current_level,
int deway [],
1122 const size_t & size,
size_t & n);
1146 template <
class Node,
1147 class Equal = Aleph::equal_to<typename Node::key_type> >
inline 1149 int deway [],
const size_t & size,
size_t & n)
1154 throw std::overflow_error(
"there is no enough space for deway array");
1156 for (
int i = 0; root !=
nullptr; i++, root = root->get_right_sibling())
1160 __search_deway <Node, Equal> (root, key, 0, deway, size, n);
1161 if (result !=
nullptr)
1168 template <
class Node,
class Equal>
inline static 1169 Node * __search_deway(Node * root,
1170 const typename Node::key_type & key,
1171 const size_t & current_level,
int deway [],
1172 const size_t & size,
size_t & n)
1175 if (current_level >= size)
1176 throw std::overflow_error(
"there is no enough space for deway array");
1178 if (root ==
nullptr)
1181 if (Equal()(root->get_key(), key))
1183 n = current_level + 1;
1187 Node * child = root->get_left_child();
1188 for (
int i = 0; child !=
nullptr;
1189 i++, child = child->get_right_sibling())
1191 deway[current_level + 1] = i;
1192 Node * result = __search_deway <Node, Equal>
1193 (child, key, current_level + 1, deway, size, n);
1195 if (result!=
nullptr)
1222 template <
class TNode,
class BNode>
1225 if (root ==
nullptr)
1226 return BNode::NullPtr;
1228 BNode * result =
new BNode (root->get_key());
1229 LLINK(result) = forest_to_bin<TNode,BNode>(root->get_left_child());
1230 RLINK(result) = forest_to_bin<TNode,BNode>(root->get_right_sibling());
1235 template <
class TNode,
class BNode>
inline static 1236 void insert_child(BNode * lnode, TNode * tree_node)
1238 if (lnode == BNode::NullPtr)
1241 TNode * child =
new TNode(
KEY(lnode));
1242 tree_node->insert_leftmost_child(child);
1245 template <
class TNode,
class BNode>
inline static 1246 void insert_sibling(BNode * rnode, TNode * tree_node)
1248 if (rnode == BNode::NullPtr)
1251 TNode * sibling =
new TNode(
KEY(rnode));
1252 tree_node->insert_right_sibling(sibling);
1255 template <
class TNode,
class BNode>
inline static 1256 void bin_to_tree(BNode * broot, TNode * troot)
1258 if (broot == BNode::NullPtr)
1261 insert_child(
LLINK(broot), troot);
1262 TNode * left_child = troot->get_left_child();
1264 bin_to_tree(
LLINK(broot), left_child);
1266 insert_sibling(
RLINK(broot), troot);
1267 TNode * right_sibling = troot->get_right_sibling();
1269 bin_to_tree(
RLINK(broot), right_sibling);
1291 template <
class TNode,
class BNode>
inline 1294 if (broot == BNode::NullPtr)
1297 TNode * troot =
new TNode (
KEY(broot));
1298 bin_to_tree(broot, troot);
1304 # endif // TPL_TREE_H T & get_key() noexcept
retorna referencia modificable al contenido del nodo.
Definition: tpl_tree_node.H:113
void empty() noexcept
empty the list
Definition: htlist.H:1598
void for_each_child(Operation &op) const
Definition: tpl_tree_node.H:501
Container< Tree_Node * > trees() const
Return a list with all trees belonging to the forrest.
Definition: tpl_tree_node.H:489
void insert_rightmost_child(Tree_Node *p) noexcept
Definition: tpl_tree_node.H:373
Container< T > children() const
Retorna una lista de los contenidos de los hijos de this.
Definition: tpl_tree_node.H:525
void insert_left_sibling(Tree_Node *p)
Definition: tpl_tree_node.H:274
#define LINKNAME_TO_TYPE(type_name, link_name)
Definition: dlink.H:937
bool is_empty() const noexcept
rioReturn true if this is empty
Definition: tpl_dynListQueue.H:112
Tree_Node * get_right_sibling() const noexcept
Retorna hermano derecho de this.
Definition: tpl_tree_node.H:171
void tree_postorder_traversal(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_tree_node.H:909
bool is_leaf() const noexcept
Retorna true si this es un nodo hoja.
Definition: tpl_tree_node.H:133
void destroy_tree(Node *root)
Definition: tpl_tree_node.H:1000
T & push(const T &item)
Definition: htlist.H:1432
bool is_empty() const noexcept
Definition: htlist.H:466
BNode * forest_to_bin(TNode *root)
Definition: tpl_tree_node.H:1223
Definition: tpl_dynListQueue.H:50
Definition: tpl_tree_node.H:67
T & get_data() noexcept
retorna referencia modificable al contenido del nodo.
Definition: tpl_tree_node.H:118
Tree_Node * get_last_tree() const
Definition: tpl_tree_node.H:479
void insert_right_sibling(Tree_Node *p) noexcept
Definition: tpl_tree_node.H:239
Node::Key_Type & KEY(Node *p) noexcept
Definition: tpl_binNode.H:318
Tree_Node * get_left_tree() const noexcept
Retorna el árbol a la izquierda de this.
Definition: tpl_tree_node.H:458
Tree_Node() noexcept
Constructor vacÃo (clave indefinida).
Definition: tpl_tree_node.H:150
Tree_Node * get_right_tree() const noexcept
Retorna el árbol a la derecha de this.
Definition: tpl_tree_node.H:467
Tree_Node * get_left_sibling() const noexcept
Retorna hermano izquierdo de this.
Definition: tpl_tree_node.H:162
TNode * bin_to_forest(BNode *broot)
Definition: tpl_tree_node.H:1292
void insert_leftmost_child(Tree_Node *p) noexcept
Definition: tpl_tree_node.H:331
void insert(Dlink *node) noexcept
Definition: dlink.H:205
Dlink *& get_prev() const noexcept
Return the link that is before this
Definition: dlink.H:248
Node * deway_search(Node *root, int path [], const size_t &size)
Definition: tpl_tree_node.H:1110
Tree_Node(const T &__data) noexcept(std::is_nothrow_copy_constructible< T >::value)
Constructor con valor de dato __data.
Definition: tpl_tree_node.H:153
Node *& LLINK(Node *p) noexcept
Definition: tpl_binNode.H:298
bool level_traverse(Node *root, Operation &operation)
Definition: tpl_binNodeUtils.H:662
bool is_leftmost() const noexcept
Retorna true si this es el nodo más a la izquierda de sus hermanos.
Definition: tpl_tree_node.H:136
void insert_tree_to_right(Tree_Node *tree)
Definition: tpl_tree_node.H:437
Definition: tpl_tree_node.H:593
T pop()
Definition: htlist.H:1543
Dlink * del() noexcept
Remove this from the list. this must not be a header node.
Definition: dlink.H:389
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:1148
Tree_Node * get_right_child() const noexcept
retorna el hijo más a la derecha de this.
Definition: tpl_tree_node.H:189
Tree_Node * get_parent() const noexcept
Retorna el padre de this.
Definition: tpl_tree_node.H:218
void append(Dlink *node) noexcept
Definition: dlink.H:228
Tree_Node * get_child(const size_t i) const noexcept
Definition: tpl_tree_node.H:208
DynList & swap(DynList &l) noexcept
Definition: htlist.H:1346
void forest_preorder_traversal(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_tree_node.H:862
Container< Tree_Node * > children_nodes() const
Retorna una lista de los nodos hijos de this.
Definition: tpl_tree_node.H:516
Dlink *& get_next() const noexcept
Return the link that is after this
Definition: dlink.H:241
bool are_tree_equal(Node *t1, Node *t2, Eq &eq) noexcept(noexcept(eq(t1->get_key(), t2->get_key())))
Definition: tpl_tree_node.H:958
bool is_root() const noexcept
Retorna true si this es la raÃz del árbol general.
Definition: tpl_tree_node.H:130
void forest_postorder_traversal(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_tree_node.H:938
T get()
Definition: tpl_dynListQueue.H:165
Tree_Node * get_left_child() const noexcept
retorna el hijo más a la izquierda de this.
Definition: tpl_tree_node.H:180
Node *& RLINK(Node *p) noexcept
Definition: tpl_binNode.H:307
char key_type
Tipo de dato genérico que contiene el nodo.
Definition: tpl_tree_node.H:123
bool is_rightmost() const noexcept
Retorna true si this es el nodo más a la derecha de sus hermanos.
Definition: tpl_tree_node.H:139
size_t compute_height(Node *root)
Definition: tpl_tree_node.H:1062
void destroy_forest(Node *root)
Definition: tpl_tree_node.H:1035
bool traverse(Operation op)
Recorre en prefijo todos los nodos y ejecuta op.
Definition: tpl_tree_node.H:558
T & put(const T &data)
The type of element.
Definition: tpl_dynListQueue.H:125
Tree_Node * join(Tree_Node *tree)
join tree as subtree of root this
Definition: tpl_tree_node.H:400
void tree_preorder_traversal(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_tree_node.H:830