43# ifndef TPL_BINNODEUTILS_H
44# define TPL_BINNODEUTILS_H
62 if (node == Node::NullPtr)
67 (*visitFct)(node, level, position);
104 template <
class Node>
109 if (p == Node::NullPtr)
112 (*visitFct)(p, level, position);
141 template <
class Node>
150 template <
class Node>
155 if (node == Node::NullPtr)
161 (*visitFct)(node, level, position);
187 template <
class Node>
211 template <
class Node>
217 if (
root == Node::NullPtr)
254 template <
class Node,
class Op>
277 template <
class Node>
283 if (
root == Node::NullPtr)
320 template <
class Node,
class Op>
342 template <
class Node>
348 if (
root == Node::NullPtr)
385 template <
class Node,
class Op>
392 template <
class Node>
395 if (
root == Node::NullPtr)
403 template <
class Node>
406 if (
root == Node::NullPtr)
414 template <
class Node>
417 if (
root == Node::NullPtr)
432 template <
class Node>
447 template <
class Node>
462 template <
class Node>
477 template <
class Node>
481 if (
root == Node::NullPtr)
489 template <
class Node>
502 template <
class Node>
505 if (
root == Node::NullPtr)
522 template <
class Node>
526 if (
root == Node::NullPtr)
532 root = Node::NullPtr;
547 template <
class Node>
551 if (
root == Node::NullPtr)
554 using Key =
typename Node::key_type;
558 root->get_key().~Key();
559 root = Node::NullPtr;
569 template <
class Node>
573 if (
root == Node::NullPtr)
574 return Node::NullPtr;
608 template <
class Node>
616 if (
t1 == Node::NullPtr
or t2 == Node::NullPtr)
634 template <
class Node,
class Equal>
641 if (
t1 == Node::NullPtr
or t2 == Node::NullPtr)
652 template <
class Node,
class Equal = std::equal_to<
typename Node::key_type>>
674 template <
class Node>
678 if (
root == Node::NullPtr)
682 queue.
put(std::pair<Node *, bool>(
root,
bool()));
686 std::pair<Node *, bool>
pr = queue.
get();
689 (*visitFct)(p, pos,
pr.second);
691 if (
LLINK(p) != Node::NullPtr)
692 queue.
put(std::pair<Node *, bool>(
LLINK(p),
true));
694 if (
RLINK(p) != Node::NullPtr)
695 queue.
put(std::pair<Node *, bool>(
RLINK(p),
false));
715 template <
class Node,
class Operation>
719 if (
root == Node::NullPtr)
730 if (
LLINK(p) != Node::NullPtr)
733 if (
RLINK(p) != Node::NullPtr)
739 template <
class Node,
class Operation>
761 template <
template <
class>
class Node,
typename Key>
782 for (
int j =
l_i; j <=
r_i; ++j)
791 <<
"build_tree: root key not found in inorder array (corrupted input)";
802 template <
template <
class>
class Node,
typename Key>
821 <<
"build_postorder: root key not found in inorder array (corrupted input)";
832 template <
class Node>
837 if (
root == Node::NullPtr)
840 if (current_level == level)
858 template <
class Node>
887 template <
class Node>
891 if (
root == Node::NullPtr)
895 while (p != Node::NullPtr)
898 if (q == Node::NullPtr)
907 while (q !=
r and RLINK(q) != Node::NullPtr)
919 RLINK(q) = Node::NullPtr;
945 template <
class Node>
949 if (node == Node::NullPtr)
952 Node *p = node, *
r = Node::NullPtr;
953 while (p != Node::NullPtr)
957 if (q == Node::NullPtr)
966 while (q !=
r and RLINK(q) != Node::NullPtr)
977 RLINK(q) = Node::NullPtr;
983 template <
class Node>
987 if (p == Node::NullPtr)
1001 template <
class Node>
1021 template <
class Node>
1025 if (
root == Node::NullPtr)
1049 template <
class Node>
1065 template <
class Node>
1069 const size_t n = bits.
size();
1072 for (
size_t i = 0; i < n; ++i)
1073 str.push_back(bits(i) ?
'b' :
'a');
1078 template <
class Node>
1084 <<
"bits_to_tree_helper: bit array index out of bounds (malformed input)";
1087 return Node::NullPtr;
1090 Node *left = Node::NullPtr;
1091 Node *right = Node::NullPtr;
1124 template <
class Node>
1148 template <
class Node>
1152 if (
root == Node::NullPtr)
1171 template <
class Node>
1175 if (
root == Node::NullPtr)
1200 template <
class Node>
1222 template <
class Node>
1242 template <
class Node,
class Get_Key>
1246 if (
root == Node::NullPtr)
1249 const std::string str = Get_Key()(
root);
1251 for (
const char ch : str)
1255 case '\n':
out <<
"\\n";
break;
1256 case '\t':
out <<
"\\t";
break;
1257 case '\\':
out <<
"\\\\";
break;
1258 case '"':
out <<
"\\\"";
break;
1259 default:
out <<
ch;
break;
1269 template <
class Node,
class Load_Key>
1273 if (
root == Node::NullPtr)
1311 template <
class Node,
class Get_Key>
1322 output <<
"nullptr };" <<
'\n';
1355 template <
class Node,
class Load_Key>
1358 const size_t & num_bits,
1370 template <
class Node,
class Compare>
1373 const typename Node::key_type *min_key,
1374 const typename Node::key_type *max_key,
1375 const Compare &
cmp)
1377 if (p == Node::NullPtr)
1380 const auto & key =
KEY(p);
1399 template <
class Node,
1419 template <
class Node,
1423 const Compare &
cmp = Compare())
1426 return Node::NullPtr;
1464 template <
typename T,
class Compare = Aleph::less<T>>
1489 template <
class Node,
1497 while (
root != Node::NullPtr)
1515 return Node::NullPtr;
1526 template <
class Node>
1530 assert(
root != Node::NullPtr &&
"find_min called on empty tree");
1545 template <
class Node>
1549 assert(
root != Node::NullPtr &&
"find_max called on empty tree");
1564 template <
class Node>
1568 assert(p != Node::NullPtr);
1573 while (
LLINK(p) != Node::NullPtr)
1590 template <
class Node>
1594 assert(p != Node::NullPtr);
1600 while (
RLINK(p) != Node::NullPtr)
1621 template <
class Node,
1672 template <
class Node,
1711 template <
class Node,
1719 const auto &
pk =
KEY(p);
1720 const auto &
rk =
KEY(
r);
1742 template <
class Node,
1751 const auto &
pk =
KEY(p);
1774 template <
class Node,
1783 const auto &
pk =
KEY(p);
1784 const auto &
rk =
KEY(
r);
1795 template <
class Node,
class Compare>
1800 if (
root == Node::NullPtr)
1802 ts =
tg = Node::NullPtr;
1846 template <
class Node,
1854 root = Node::NullPtr;
1859 template <
class Node,
class Compare>
1864 if (
root == Node::NullPtr)
1866 ts =
tg = Node::NullPtr;
1897 template <
class Node,
1904 root = Node::NullPtr;
1921 template <
class Node>
1925 if (
ts == Node::NullPtr)
1928 if (
tg == Node::NullPtr)
1935 ts =
tg = Node::NullPtr;
1951 template <
class Node,
1957 if (
root == Node::NullPtr)
1958 return Node::NullPtr;
1987 template <
class Node,
1992 Node *
l = Node::NullPtr, *
r = Node::NullPtr;
1995 return Node::NullPtr;
2014 template <
class Node,
2037 template <
class Node,
2043 if (
t2 == Node::NullPtr)
2074 template <
class Node,
2080 if (
t1 == Node::NullPtr)
2083 if (
t2 == Node::NullPtr)
2095 assert(p != Node::NullPtr);
2111 template <
class Node>
2115 assert(p != Node::NullPtr);
2131 template <
class Node>
2135 assert(p != Node::NullPtr);
2156 template <
class Node>
2160 assert(p != Node::NullPtr);
2175 template <
class Node>
2179 assert(p != Node::NullPtr);
2210 template <
class Node,
class Key,
2216 assert(
l == Node::NullPtr
and r == Node::NullPtr);
2217 if (
root == Node::NullPtr)
2219 l =
r = Node::NullPtr;
2239 while (current != Node::NullPtr)
2241 if (
cmp(key,
KEY(current)))
2264 root = Node::NullPtr;
2276 template <
class Node>
2285 pp != Node::NullPtr
and pq != Node::NullPtr);
2297 LLINK(p) = Node::NullPtr;
2330 template <
class Node>
2338 assert((p != Node::NullPtr)
and (q != Node::NullPtr)
and
2339 (
pp != Node::NullPtr)
and (
pq != Node::NullPtr));
2351 RLINK(p) = Node::NullPtr;
2387 template <
class Node,
class Key =
typename Node::key_type,
2393 if (
root == Node::NullPtr)
2400 return Node::NullPtr;
2409 return Node::NullPtr;
2415 return Node::NullPtr;
2430 template <
class Node,
class Key =
typename Node::key_type,
2436 if (
root == Node::NullPtr)
2475 template <
class Node>
2486 std::swap(
root, it.root);
2487 std::swap(
curr, it.curr);
2523 if (
RLINK(p) != Node::NullPtr)
2526 if (
LLINK(p) != Node::NullPtr)
2537 if (
root == Node::NullPtr)
2539 curr = Node::NullPtr;
2549 curr = Node::NullPtr;
2588 if (
l != Node::NullPtr)
2591 if (
r != Node::NullPtr)
2596 if (
r != Node::NullPtr)
2603 curr = Node::NullPtr;
2639 template <
class Node,
class Op>
2643 if (
not op(it.get_curr()))
2667 template <
class Node,
class Op>
2682 template <
class Node>
2692 while (
LLINK(
r) != Node::NullPtr)
2702 while (
RLINK(
r) != Node::NullPtr)
2710 if (
root != Node::NullPtr)
2729 std::swap(
root, it.root);
2730 std::swap(
curr, it.curr);
2731 std::swap(
pos, it.pos);
2739 :
root(
r),
s(Node::MaxHeight)
2763 if (
root == Node::NullPtr)
2765 curr = Node::NullPtr;
2777 curr = Node::NullPtr;
2820 if (
curr != Node::NullPtr)
2827 curr = Node::NullPtr;
2864 template <
class Node,
class Op>
2868 if (
not op(it.get_curr()))
2877 template <
class Node,
class Op>
2901 template <
class Node,
class Op>
Exception handling system with formatted messages for Aleph-w.
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
#define ah_runtime_error_if(C)
Throws std::runtime_error if condition holds.
Standard functor implementations and comparison objects.
WeightedDigraph::Node Node
Space-efficient bit array implementation.
EepicNode< long > * build_tree()
Stack implemented with simple dynamic array and with bounds verification.
void swap(ArrayStack &s) noexcept
Swap this with s
void empty() noexcept
Empty the stack.
bool is_empty() const noexcept
Return true if stack is empty.
T pop()
Extract the last more recently inserted element.
T & push(const T &data)
Push into stack a copy of data
Inorder iterator on the nodes of a binary tree.
BinNodeInfixIterator()=default
Node * get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
void next()
Move the iterator one position forward.
void reset_last() noexcept
Reset the iterator to the first node inorder.
Node * get_curr() const
Return the current node. Throw overflow_error if there is no current.
BinNodeInfixIterator(const BinNodeInfixIterator &it)
bool is_last() const noexcept
bool has_curr() const noexcept
Return true the iterator has current node.
BinNodeInfixIterator(Node *r) noexcept
Initialize an iterator on the first node inorder.
bool is_in_first() const noexcept
Return true if the iterator is on the first node.
BinNodeInfixIterator(BinNodeInfixIterator &&it) noexcept
BinNodeInfixIterator & operator=(const BinNodeInfixIterator &it)
Node * advance_to_min(Node *r) noexcept
static Node * advance_to_max(Node *r) noexcept
size_t get_pos() const
Return the current position of iterator. Only valid if has_curr() == true.
void swap(BinNodeInfixIterator &it) noexcept
void reset_first() noexcept
Reset the iterator to the first node inorder.
Preorder iterator on the nodes of a binary tree.
void next_ne() noexcept
Move the iterator one position forward guaranteeing no exception.
Node * get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
bool has_curr() const noexcept
Return true if iterator has current node.
BinNodePrefixIterator(BinNodePrefixIterator &&it) noexcept
Node * get_curr() const
Return a pointer to current node.
void reset_first() noexcept
Reset the iterator to the first node in preorder sense.
void reset_last() noexcept
Reset the iterator to the last node in preorder.
BinNodePrefixIterator(Node *r) noexcept
Initialize an iterator on the first node in preorder for the tree with root r
void next()
Move the iterator one position forward.
void swap(BinNodePrefixIterator &it) noexcept
Swap thiswith it
BinNodePrefixIterator & operator=(const BinNodePrefixIterator &it)
void end() noexcept
Put the iterator in end state.
BinNodePrefixIterator()=default
BinNodePrefixIterator(const BinNodePrefixIterator &it)
static Node * last(Node *p) noexcept
Contiguous array of bits.
int read_bit(const size_t i) const
Read bit i.
void load_from_array_of_chars(const unsigned char str[], const size_t num_bits)
Reads an array of bits saved in a character array.
void load(std::istream &input)
Loads an array of bits from a file.
void push(const unsigned int value)
Inserts the value at the end of the array.
constexpr size_t size() const noexcept
Returns the dimension of the bit array.
Dynamic doubly linked list with O(1) size and bidirectional access.
Dynamic queue of elements of generic type T based on single linked list.
T & put(const T &data)
The type of element.
T get()
Remove the oldest item of the queue.
bool is_empty() const noexcept
Return true if this is empty.
Dynamic singly linked list with functional programming support.
Generic inorder traversal of a binary tree.
void traverse(Node *root, Op &&op) const
Invoke to traversal from root node.
static void for_each_inorder(Node *root, Op &&op)
void operator()(Node *root, Op &op) const
Generic postorder traversal of a binary tree.
void operator()(Node *root, Op &op) const
static void postorder(Node *root, Op &&op)
void traverse(Node *root, Op &&op) const
Invoke the traversal.
Generic preorder traversal of a binary tree.
static void preorder(Node *root, Op &&op)
void traverse(Node *root, Op &&op) const
Invoke the traversal.
void operator()(Node *root, Op &op) const
__gmp_expr< T, __gmp_binary_expr< __gmp_expr< T, U >, unsigned long int, __gmp_root_function > > root(const __gmp_expr< T, U > &expr, unsigned long int l)
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
bool prefix_traverse(Node *root, Op op)
Traverse a tree in preorder via its iterator and performs a conditioned operation on each item.
int postOrderRec(Node *root, void(*visitFct)(Node *, int, int))
Traverse recursively in postorder a binary tree.
size_t compute_cardinality_rec(Node *root) noexcept
Count the number of nodes of a binary tree.
Node * rotate_to_left(Node *p) noexcept
Rotate to the left the tree with root p
int preOrderRec(Node *root, void(*visitFct)(Node *, int, int))
Traverse recursively in preorder a binary tree.
void save_tree_in_array_of_chars(Node *root, const std::string &array_name, std::ostream &output)
Generate C++ array declarations for a binary tree.
Node * search_rank_parent(Node *root, const typename Node::key_type &key, const Compare &cmp=Compare()) noexcept
Rank search of a key in a binary search tree.
void save_tree_keys_in_prefix(Node *root, std::ostream &output)
Store in output stream the tree keys in preorder.
void load_tree_keys_in_prefix(Node *root, std::istream &input)
Load the keys stored in preorder from an input stream.
bool level_traverse(Node *root, Operation &operation)
Level traverse a tree and execute an operation.
DynDlist< Node * > compute_nodes_in_level(Node *root, const int &level)
Count the number of nodes in a specific tree level.
Node * join_preorder(Node *t1, Node *t2, Node *&dup, const Compare &cmp=Compare()) noexcept
Union of two binary search trees.
void swap_node_with_successor(Node *p, Node *&pp, Node *q, Node *&pq) noexcept
Swap a node with its successor inorder.
Node * remove_from_bst(Node *&root, const typename Node::key_type &key, const Compare &cmp=Compare()) noexcept
Remove a key from a binary search tree.
void for_each_in_order(Node *root, Op &&op)
Execute an operation in order sense for each node of tree.
Node * find_predecessor(Node *p, Node *&pp) noexcept
Find the inorder predecessor of p
Node * load_tree_from_array(const unsigned char bits[], const size_t &num_bits, const char *keys[])
Build a binary tree from two arrays.
Node * search_parent(Node *root, const typename Node::key_type &key, Node *&parent, const Compare &cmp=Compare()) noexcept
Search a key and find its node and parent.
Node * find_min(Node *root) noexcept
Return the minimum key contained in a binary search tree.
Node * rotate_to_right(Node *p) noexcept
Rotate to the right the tree with root p
bool split_key_rec(Node *&root, const typename Node::key_type &key, Node *&ts, Node *&tg, const Compare &cmp=Compare()) noexcept
Split recursively according to a key.
Node * find_successor(Node *p, Node *&pp) noexcept
Find the inorder successor of p
Node * copyRec(Node *root)
Copy recursively a tree.
void for_each_postorder(Node *root, Op &&op)
Execute an operation in postorder sense for each node of tree.
Node * load_tree(std::istream &input)
Load and build a binary tree from a stream.
void for_each_preorder(Node *root, Op &&op)
Execute an operation in preorder sense for each node of tree.
Node * search_or_insert_in_bst(Node *&r, Node *p, const Compare &cmp=Compare()) noexcept
Search or insert a node in a binary search tree.
void save_tree(Node *root, std::ostream &output)
Store a binary tree in a stream.
void split_key_dup_rec(Node *&root, const typename Node::key_type &key, Node *&ts, Node *&tg, const Compare &cmp=Compare()) noexcept
Split a tree according to a key value.
ThreeWayCmp three_way_compare(const T &a, const T &b, const Compare &cmp=Compare()) noexcept
Three-way comparison using a binary comparator.
bool check_bst(Node *p, const Compare &cmp=Compare())
Return true if p is a binary search tree.
Node * bits_to_tree(const BitArray &array, int idx=0)
Build a binary tree given its bits code.
Node * insert_in_bst(Node *&r, Node *p, const Compare &cmp=Compare()) noexcept
Insert a node p in a binary search tree.
void tree_to_bits(Node *root, BitArray &array)
Compute a bit code for the binary tree.
size_t internal_path_length(Node *p) noexcept
Compute the internal path length.
void preOrderThreaded(Node *node, void(*visitFct)(Node *))
Traverse preorder a binary tree without recursion and without stack.
void inOrderThreaded(Node *root, void(*visitFct)(Node *))
Traverse inorder a binary tree without recursion and without stack.
Node * preorder_to_bst(DynArray< typename Node::key_type > &preorder, int l, int r, const Compare &cmp=Compare())
Build a binary search tree from its preorder traversal.
void levelOrder(Node *root, void(*visitFct)(Node *, int, bool))
Traverse a binary tree by levels.
int inOrderRec(Node *root, void(*visitFct)(Node *, int, int))
Traverse recursively inorder a binary tree.
Node * join_exclusive(Node *&ts, Node *&tg) noexcept
Exclusive join of two binary trees.
void destroyRec(Node *&root) noexcept
Free recursively all the memory occupied by the tree root
Node * searchInBinTree(Node *root, const typename Node::key_type &key, const Compare &cmp=Compare()) noexcept
Search a key in a binary search tree.
Node * search_or_insert_root_rec(Node *root, Node *p, const Compare &cmp=Compare()) noexcept
Search and eventually insert p as root in a binary search tree.
Node * insert_dup_in_bst(Node *&root, Node *p, const Compare &cmp=Compare()) noexcept
Insert a node p in a binary search tree.
Node * insert_root(Node *&root, Node *p, const Compare &cmp=Compare()) noexcept
Insert the node p as root of a binary search tree.
Node * insert_dup_root(Node *&root, Node *p, const Compare &cmp=Compare()) noexcept
Insert node p as root of a binary search tree.
void swap_node_with_predecessor(Node *p, Node *&pp, Node *q, Node *&pq) noexcept
Swap a node with its predecessor inorder.
Node * insert_root_rec(Node *root, Node *p, const Compare &cmp=Compare()) noexcept
Insert a node as root in a binary search tree.
bool infix_traverse(Node *root, Op op)
Traverse a tree in inorder via its iterator and performs a conditioned operation on each item.
size_t computeHeightRec(Node *root) noexcept
Compute recursively the height of root
Node * find_max(Node *root) noexcept
Return the maximum key contained in a binary search tree.
void split_key(Node *&root, const Key &key, Node *&l, Node *&r, const Compare &cmp=Compare()) noexcept
Split a binary search tree according to a key.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
size_t size(Node *root) noexcept
static Node * bits_to_tree_helper(const BitArray &array, int &i)
static void infix(Node *root, DynList< Node * > &acc)
bool traverse(Node *root, Op op)
static void suffix(Node *root, DynList< Node * > &acc)
void infix_for_each(Node *root, Op op)
Traverse all the container and performs an operation on each element.
void load_tree_keys_from_array(Node *root, const char *keys[], int &idx)
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
std::decay_t< typename HeadC::Item_Type > T
std::string code(Node *root)
Compute a string with the Lukasiewicz`s word of a tree.
static void prefix(Node *root, DynList< Node * > &acc)
static void compute_nodes_in_level_helper(Node *root, long level, const long current_level, DynDlist< Node * > &level_list)
static void postorder_rec_helper(Node *node, const int &level, int &position, void(*visitFct)(Node *, int, int))
static void split_key_dup_rec_helper(Node *root, const typename Node::key_type &key, Node *&ts, Node *&tg, Compare &cmp) noexcept
static bool split_key_rec_helper(Node *root, const typename Node::key_type &key, Node *&ts, Node *&tg, Compare &cmp) noexcept
bool less_or_equal_than(const T &op1, const T &op2, Compare &cmp)
Determines if op1 is less than or equal to op2 using a comparison operator.
void put_tree_keys_in_array(Node *root, std::ostream &out)
Node< Key > * build_postorder(const DynArray< Key > &post, long lp, long rp, const DynArray< Key > &in, long li, long ri)
ThreeWayCmp
Constants for three-way comparison results.
@ CmpGreater
First argument is greater than second.
@ CmpLess
First argument is less than second.
@ CmpEqual
Arguments are equal.
bool areEquivalents(Node *t1, Node *t2, Equal &op) noexcept
Return true if trees are equivalents.
static void preorder_rec_helper(Node *p, const int &level, int &position, void(*visitFct)(Node *, int, int))
std::ostream & join(const C &c, const std::string &sep, std::ostream &out)
Join elements of an Aleph-style container into a stream.
bool areSimilar(Node *t1, Node *t2) noexcept
Return true if both trees are similar.
static bool check_bst_range(Node *p, const typename Node::key_type *min_key, const typename Node::key_type *max_key, const Compare &cmp)
static void inorder_rec_helper(Node *node, const int &level, int &position, void(*visitFct)(Node *, int, int))
static size_t internal_path_length_helper(Node *p, const size_t &level) noexcept
void callKeyDestructorsRec(Node *&root) noexcept
Traverses recursively the tree and calls key's destructors.
void prefix_for_each(Node *root, Op op)
Traverse in preorder all the container and performs an operation on each element.
DynArray< int > postorder
Circular queue implementations backed by arrays.
Stack implementations backed by dynamic or fixed arrays.
Basic binary tree node definitions.
Dynamic doubly linked list implementation.
Dynamic queue implementation based on linked lists.