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)
1276 if (Load_Key()(
root, keys[idx]))
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)
1504 if (
next != Node::NullPtr)
1516 return Node::NullPtr;
1527 template <
class Node>
1531 assert(
root != Node::NullPtr &&
"find_min called on empty tree");
1546 template <
class Node>
1550 assert(
root != Node::NullPtr &&
"find_max called on empty tree");
1565 template <
class Node>
1569 assert(p != Node::NullPtr);
1574 while (
LLINK(p) != Node::NullPtr)
1591 template <
class Node>
1595 assert(p != Node::NullPtr);
1601 while (
RLINK(p) != Node::NullPtr)
1622 template <
class Node,
1673 template <
class Node,
1712 template <
class Node,
1717 if (r == Node::NullPtr) [[
unlikely]]
1720 const auto &
pk =
KEY(p);
1721 const auto &
rk =
KEY(r);
1743 template <
class Node,
1752 const auto &
pk =
KEY(p);
1775 template <
class Node,
1781 if (r == Node::NullPtr) [[
unlikely]]
1784 const auto &
pk =
KEY(p);
1785 const auto &
rk =
KEY(r);
1796 template <
class Node,
class Compare>
1801 if (
root == Node::NullPtr)
1803 ts =
tg = Node::NullPtr;
1847 template <
class Node,
1855 root = Node::NullPtr;
1860 template <
class Node,
class Compare>
1865 if (
root == Node::NullPtr)
1867 ts =
tg = Node::NullPtr;
1898 template <
class Node,
1905 root = Node::NullPtr;
1922 template <
class Node>
1926 if (
ts == Node::NullPtr)
1929 if (
tg == Node::NullPtr)
1936 ts =
tg = Node::NullPtr;
1952 template <
class Node,
1958 if (
root == Node::NullPtr)
1959 return Node::NullPtr;
1988 template <
class Node,
1993 Node *
l = Node::NullPtr, *r = Node::NullPtr;
1996 return Node::NullPtr;
2015 template <
class Node,
2038 template <
class Node,
2044 if (
t2 == Node::NullPtr)
2075 template <
class Node,
2081 if (
t1 == Node::NullPtr)
2084 if (
t2 == Node::NullPtr)
2096 assert(p != Node::NullPtr);
2112 template <
class Node>
2116 assert(p != Node::NullPtr);
2132 template <
class Node>
2136 assert(p != Node::NullPtr);
2157 template <
class Node>
2161 assert(p != Node::NullPtr);
2176 template <
class Node>
2180 assert(p != Node::NullPtr);
2211 template <
class Node,
class Key,
2217 assert(
l == Node::NullPtr
and r == Node::NullPtr);
2218 if (
root == Node::NullPtr)
2220 l = r = Node::NullPtr;
2240 while (current != Node::NullPtr)
2242 if (
cmp(key,
KEY(current)))
2265 root = Node::NullPtr;
2277 template <
class Node>
2286 pp != Node::NullPtr
and pq != Node::NullPtr);
2298 LLINK(p) = Node::NullPtr;
2331 template <
class Node>
2339 assert((p != Node::NullPtr)
and (q != Node::NullPtr)
and
2340 (
pp != Node::NullPtr)
and (
pq != Node::NullPtr));
2352 RLINK(p) = Node::NullPtr;
2388 template <
class Node,
class Key =
typename Node::key_type,
2394 if (
root == Node::NullPtr)
2401 return Node::NullPtr;
2410 return Node::NullPtr;
2416 return Node::NullPtr;
2431 template <
class Node,
class Key =
typename Node::key_type,
2437 if (
root == Node::NullPtr)
2476 template <
class Node>
2487 std::swap(
root, it.root);
2488 std::swap(
curr, it.curr);
2524 if (
RLINK(p) != Node::NullPtr)
2527 if (
LLINK(p) != Node::NullPtr)
2538 if (
root == Node::NullPtr)
2540 curr = Node::NullPtr;
2550 curr = Node::NullPtr;
2589 if (
l != Node::NullPtr)
2592 if (r != Node::NullPtr)
2597 if (r != Node::NullPtr)
2604 curr = Node::NullPtr;
2640 template <
class Node,
class Op>
2644 if (
not op(it.get_curr()))
2668 template <
class Node,
class Op>
2683 template <
class Node>
2693 while (
LLINK(r) != Node::NullPtr)
2703 while (
RLINK(r) != Node::NullPtr)
2711 if (
root != Node::NullPtr)
2730 std::swap(
root, it.root);
2731 std::swap(
curr, it.curr);
2732 std::swap(
pos, it.pos);
2740 :
root(r),
s(Node::MaxHeight)
2764 if (
root == Node::NullPtr)
2766 curr = Node::NullPtr;
2778 curr = Node::NullPtr;
2821 if (
curr != Node::NullPtr)
2828 curr = Node::NullPtr;
2865 template <
class Node,
class Op>
2869 if (
not op(it.get_curr()))
2878 template <
class Node,
class Op>
2902 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.
T & append(const T &item)
Append a new item by copy.
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.
constexpr Node *& RLINK(Node *p) noexcept
Return the right tree of p.
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.
constexpr Node *& LLINK(Node *p) noexcept
Return a pointer to left subtree.
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.
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)
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.
void next()
Advance all underlying iterators (bounds-checked).
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
DynList< T > maps(const C &c, Op op)
Classic map operation.
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.
bool traverse(Operation &operation) noexcept(traverse_is_noexcept< Operation >())
Traverse the container via its iterator and performs a conditioned operation on each item.
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.
void preorder(int v[], int n, int i)
Write preorder traversal of heap.
void inorder(int v[], int n, int i)
Write inorder traversal of heap.