45# ifndef TPL_DYNSETTREE_H
46# define TPL_DYNSETTREE_H
50# include <type_traits>
82 template <
typename Node>
97 template <
typename Node>
103 return new Node(key);
108 return new Node(std::forward<typename Node::key_type>(key));
119 template <
typename Node>
131 :
arena(base_addr, sz)
169 template <
typename Container,
typename T>
174 return std::lexicographical_compare(
c1.begin(),
c1.end(),
c2.begin(),
c2.end(),
177 return item1 < item2;
265 template <
typename Key,
273 public GenericKeys<DynSetTree<Key, Tree, Compare>, Key>,
285 template <
typename T>
291 requires(
const T & t) { t.select(std::declval<size_t>()); }
or
292 requires(
T & t) { t.select(std::declval<size_t>()); };
294 requires(
T & t) { t.remove_pos(std::declval<size_t>()); };
296 requires(
T & t,
T &
l,
T &
r) { t.split_pos(std::declval<size_t>(),
l,
r); };
298 requires(
const T & t,
const Key &
k) { t.position(
k); }
or
299 requires(
T & t,
const Key &
k) { t.position(
k); };
301 requires(
const T & t,
const Key &
k) { t.find_position(
k); }
or
302 requires(
T & t,
const Key &
k) { t.find_position(
k); };
306 template <
typename T>
308 ->
decltype(t.select(i))
314 template <
typename T>
316 ->
decltype(t.select(i))
321 template <
typename T>
328 template <
typename T>
335 template <
typename T>
337 ->
decltype(t.remove_pos(i))
339 return t.remove_pos(i);
342 template <
typename T>
349 template <
typename T>
351 ->
decltype(t.split_pos(pos,
l,
r),
void())
353 t.split_pos(pos,
l,
r);
356 template <
typename T>
362 template <
typename T>
364 ->
decltype(t.position(key))
366 return t.position(key);
369 template <
typename T>
373 return std::pair<long, Node *>(0,
nullptr);
376 template <
typename T>
378 ->
decltype(t.find_position(key))
380 return t.find_position(key);
383 template <
typename T>
386 ah_domain_error() <<
"find_position is not supported by underlying tree";
387 return std::pair<long, Node *>(0,
nullptr);
390 static constexpr size_t dim = 13;
400 return new Node(key);
407 return new Node(std::forward<Key>(key));
449 const Compare &
cmp = Compare())
458 const Compare &
cmp = Compare())
499 tree.getRoot() = Node::NullPtr;
505 tree.getRoot() = Node::NullPtr;
561 q =
tree.search_or_insert(p);
574 return &p->get_key();
590 if (
key_p ==
nullptr)
603 if (
key_p ==
nullptr)
619 return insert(std::forward<Key>(key));
628 q =
tree.search_or_insert(p);
641 return &q->get_key();
649 q =
tree.search_or_insert(p);
659 return std::pair<Node *, bool>(q,
true);
662 return std::pair<Node *, bool>(p,
false);
705 return std::pair<Key *, bool>(&p.first->get_key(), p.second);
711 return std::pair<Key *, bool>(&p.first->get_key(), p.second);
721 return &p->get_key();
741 Key *
put(
const Key & key)
748 return insert(std::forward<Key>(key));
785 <<
"DynSetTree::del key is not found in the tree";
803 <<
"remove_pos is not supported by underlying tree";
806 <<
"remove_pos index out of range";
810 <<
"remove_pos returned nullptr";
823 return search(key) !=
nullptr;
826 bool has(
const Key & key)
const
856 Key &
find(
const Key & key)
const
863 return node->get_key();
883 <<
"find_position is not supported by underlying tree";
886 return std::pair<long, Key *>(0,
nullptr);
889 if (p.second ==
nullptr)
890 return std::pair<long, Key *>(
static_cast<long>(p.first),
nullptr);
892 return std::pair<long, Key *>(
static_cast<long>(p.first),
893 &p.second->get_key());
917 return &(node->get_key());
1023 <<
"position is not supported by underlying tree";
1026 return static_cast<long>(p.first);
1037 <<
"select is not supported by underlying tree";
1040 <<
"select index out of range";
1045 <<
"select returned nullptr";
1046 return p->get_key();
1052 <<
"select is not supported by underlying tree";
1055 <<
"select index out of range";
1060 <<
"select returned nullptr";
1061 return p->get_key();
1090 template <
class Key_Op>
1136 template <
class Key_Op>
1153 template <
class Key_Op>
1183 template <
class Key_Op>
1200 template <
class Key_Op>
1230 template <
class Key_Op>
1247 template <
class Key_Op>
1268 t.
tree.getRoot() = Node::NullPtr;
1286 return join(t, dup);
1305 t.
tree.getRoot() = Node::NullPtr;
1327 if (
not tree.split_key(key,
l.tree,
r.tree))
1330 tree.getRoot() = Node::NullPtr;
1353 <<
"split_pos is not supported by underlying tree";
1356 <<
"split_pos position out of range";
1361 tree.getRoot() = Node::NullPtr;
1381 tree.split_key_dup(key,
l.tree,
r.tree);
1382 tree.getRoot() = Node::NullPtr;
1390 using Base =
typename Tree_Type::Iterator;
1403 return Base::get_curr_ne()->get_key();
1408 const Key &
get_curr()
const {
return Base::get_curr()->get_key(); }
1410 Key &
get_curr() {
return Base::get_curr()->get_key(); }
1427 template <
class Operation>
1432 return op(p->get_key());
1436 template <
class Operation>
1442 template <
class Operation>
1447 return op(p->get_key());
1451 template <
class Operation>
1459# define SETTREE_ITOR(Name, Key, Cmp) \
1460 class Iterator : public DynSetTree<Key, Name, Cmp>::Iterator \
1463 Iterator() : DynSetTree<Key, Name, Cmp>::Iterator() \
1466 Iterator(DynSetTree<Key, Name, Cmp> & tree) \
1467 : DynSetTree<Key, Name, Cmp>::Iterator(tree) \
1478 template <
typename Key,
class Compare = Aleph::less<Key>>
1493 template <
typename Key,
class Compare = Aleph::less<Key>>
1508 template <
typename Key,
class Compare = Aleph::less<Key>>
1530 template <
typename Key,
class Compare = Aleph::less<Key>>
1546 template <
typename Key,
class Compare = Aleph::less<Key>>
1574 template <
typename Key,
class Compare = Aleph::less<Key>>
1588 template <
typename Key,
class Compare = Aleph::less<Key>>
1606 template <
typename Key,
class Compare = Aleph::less<Key>>
1622 template <
typename Key,
class Compare = Aleph::less<Key>>
1641 template <
typename Key,
class Compare = Aleph::less<Key>>
1658 template <
typename Key,
class Compare = Aleph::less<Key>>
1677 template <
typename Key,
class Compare = Aleph::less<Key>>
1700 template <
typename Key,
class Compare = Aleph::less<Key>>
1723 template <
typename Key,
class Compare = Aleph::less<Key>>
1733 template <
typename T,
class Op,
class C>
1737 for (
auto it = c.get_it(); it.has_curr(); it.next_ne())
Memory arena for fast bulk allocations.
Variadic constructor macros for containers.
C++20 concepts hub: comparison, BST policy, and Aleph container concepts.
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error()
Throws std::domain_error unconditionally.
#define ah_domain_error_if_constexpr(C)
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
#define ah_logic_error_if(C)
Throws std::logic_error if condition holds.
#define ah_bad_alloc_if(C)
Throws std::bad_alloc if condition holds.
Zip iterators and functional operations for multiple containers.
#define Special_Ctors(Set_Type, Type)
Generates special constructors for containers.
Iterator traits and STL-compatible iterator wrappers.
WeightedDigraph::Node Node
virtual void unalloc(Node *)=0
virtual Node * alloc_rval(typename Node::key_type &&key)=0
virtual Node * alloc_lval(const typename Node::key_type &key)=0
AbstractTreeNodeAllocator()=default
virtual ~AbstractTreeNodeAllocator()=default
Arena allocator for fast bump-pointer allocation.
size_t allocated_size() const noexcept
Get total bytes currently allocated.
size_t available_size() const noexcept
Get remaining bytes available.
~DftTreeNodeAllocator() override=default
Node * alloc_lval(const typename Node::key_type &key) override
Node * alloc_rval(typename Node::key_type &&key) override
void unalloc(Node *p) override
Doubly-linked list (defined in tpl_dynList.H).
Dynamic set implemented using extended AVL binary search trees with rank support of type Avl_Tree_Rk<...
Dynamic set implemented using AVL binary search trees of type Avl_Tree<Key>.
Dynamic set implemented using binary search trees of type BinTree<Key>.
Dynamic set implemented using Hybrid Red-Black trees with rank support of type HtdRbTreeRk<Key>.
Dynamic set implemented using Hybrid Top-Down/Bottom-Up Red-Black trees of type HtdRbTree<Key>.
Iterator(DynSetTree< Key, Rand_Tree, Compare > &tree)
Dynamic set implemented using randomized binary search trees of type Rand_Tree<Key>.
Dynamic set implemented using extended Red-Black binary search trees with rank support of type Rb_Tre...
Dynamic set implemented using Red-Black binary search trees of type Rb_Tree<Key> (bottom-up implement...
Dynamic set implemented using splay trees with rank support of type Splay_Tree_Rk<Key>.
Dynamic set implemented using splay binary search trees of type Splay_Tree<Key>.
Dynamic set implemented using Top-Down Red-Black binary search trees with rank support of type TdRbTr...
Dynamic set implemented using Top-Down Red-Black binary search trees of type TdRbTree<Key>.
Dynamic set implemented using extended treap binary search trees with rank support of type Treap_Rk<K...
Dynamic set implemented using randomized treap binary search trees of type Treap<Key>.
Dynamic set backed by balanced binary search trees with automatic memory management.
const Key & get_first() const
size_t height() const
Calculates and returns the height of the binary search tree.
DynSetTree(const Compare &cmp=Compare())
Instantiate a dynamic set.
virtual ~DynSetTree()
Destroyer; all elements are released.
long position(const Key &key) const
Returns the infix (ordered) position of the key.
Key * append(const Key &key)
const Key & get_last() const
Key * __insert_dup(Node *q)
bool split_key(const Key &key, DynSetTree &l, DynSetTree &r)
Partitions the binary search tree based on a key.
typename Tree< Key, Compare >::Node Node
Type of binary node used by the binary search tree internal.
std::pair< Key *, bool > contains_or_insert(Key &&key)
const Key & get_item() const
Returns any element of the set.
DynSetTree & join(DynSetTree &t, DynSetTree &&dup=DynSetTree())
This is an overloaded member function, provided for convenience. It differs from the above function o...
Key & operator()(size_t i)
const size_t & size() const
Returns the cardinality of the set.
Key remove_pos(const size_t i)
Removes a key from the dynamic set.
static auto call_select(const T &t, const size_t i, int) -> decltype(t.select(i))
Node * alloc_node(const Key &key)
static auto call_find_position(const T &t, const Key &key, int) -> decltype(t.find_position(key))
static auto call_split_pos(T &t, const size_t pos, T &l, T &r, int) -> decltype(t.split_pos(pos, l, r), void())
static constexpr size_t dim
Key del(const Key &key)
Deletes key and returns a full copy of stored key.
void clear()
Empties the container.
std::pair< long, Key * > find_position(const Key &key) const
Returns the infix (ordinate) position of the key key or whatever It would be your position of belongi...
DynSetTree(const DynSetTree &srcTree)
instantiates a dynamic copy of srcTree
Tree< Key, Compare > tree
const Key & operator[](const Key &key) const
Key * insert(const Key &key)
Inserts a key into the dynamic set.
bool exist(const Key &key) const
Returns true if key belongs to the dynamic set.
void split_key_dup(const Key &key, DynSetTree &l, DynSetTree &r)
Partitions the binary search tree based on a key that may be present in the tree.
bool has(const Key &key) const
void swap(DynSetTree &dset) noexcept(noexcept(tree.swap(dset.tree)) and noexcept(std::swap(num_nodes, dset.num_nodes)) and noexcept(std::swap(arena_allocator, dset.arena_allocator)))
Exchange all elements of this set with dset in constant time (and extremely fast).
void for_each_postorder(Key_Op &key_op) const
Performs a postfix traversal over all keys in the set and invokes operation Op.
Key * put(const Key &key)
static std::pair< long, Node * > call_position(const T &, const Key &,...)
Key & find(const Key &key) const
Returns a modifiable reference to an element within the set.
size_t internal_path_length() const
Calculates and returns the length of the internal path of the tree search binary.
size_t remove(const Key &key)
Removes a key from the dynamic set.
std::unique_ptr< ArenaTreeAllocator< Node > > arena_allocator
bool traverse(Operation &&op=Operation()) const
const Key & min() const
Returns the smallest key contained in the set according to the criterion comparison given.
bool contains(const Key &key) const
Checks if a key exists in the set.
const Key & get() const
Synonym of max.
const Key & get_root() const
DynSetTree(const size_t &arena_sz, const Compare &cmp=Compare())
Instantiate a dynamic set using an arena allocator with dynamic buffer.
Key * search_or_insert(Key &&key)
Node * alloc_node(Key &&key)
Key * insert_dup(const Key &key)
void for_each_preorder(Key_Op &&key_op=Key_Op()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
DynSetTree(DynSetTree &&srcTree) noexcept
void split_pos(const size_t pos, DynSetTree &l, DynSetTree &r)
Partitions the binary search tree based on an infix position.
void for_each_postorder(Key_Op &&key_op=Key_Op()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void for_each_in_preorder(void(*visitFct)(Node *, int, int))
Performs a prefix traversal over all nodes in the tree and invokes the visitFct operation on each vis...
DynSetTree(const char *base_addr, const size_t &sz, const Compare &cmp=Compare())
Instantiate a dynamic set using an arena allocator with external buffer.
static Node * call_select_nc(T &, const size_t,...)
static auto call_position(const T &t, const Key &key, int) -> decltype(t.position(key))
bool traverse(Operation &&op=Operation())
size_t arena_allocated_size() const noexcept
Returns the allocated size from the arena (0 if not using arena)
Key * search(const Key &key) const
Find an element in the set.
Key & select(size_t i)
Returns the ith node in infix position.
Key * __search_or_insert(Node *p)
static auto call_select_nc(T &t, const size_t i, int) -> decltype(t.select(i))
std::pair< Node *, bool > __contains_or_insert(Node *p)
void empty()
remove all elements from the set
bool uses_arena() const noexcept
Returns true if the set is using an arena allocator.
static auto call_remove_pos(T &t, const size_t i, int) -> decltype(t.remove_pos(i))
bool traverse(Operation &op)
Traverse all the set of pairs and for each key executes the operation op.
static Node * call_select(const T &, const size_t,...)
bool traverse(Operation &op) const
void for_each_inorder(Key_Op &&key_op=Key_Op()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
const Key & select(size_t i) const
DynSetTree & operator=(const DynList< Key > &list)
Key * search_or_insert(const Key &key)
Look for the key in the binary search tree or inserts it if it is not found.
static void call_split_pos(T &, const size_t, T &, T &,...)
void for_each_preorder(Key_Op &key_op) const
Performs a prefix traversal over all keys in the set and invokes operation Op.
const Key & max() const
Returns the largest key contained in the set according to the criteria comparison given.
static Node * call_remove_pos(T &, const size_t,...)
void for_each_inorder(Key_Op &key_op) const
Performs an infix traversal over all keys in the set and invokes operation Op.
std::pair< Key *, bool > contains_or_insert(const Key &key)
bool is_empty() const
returns true if the set is empty
static std::pair< long, Node * > call_find_position(const T &, const Key &,...)
Key * insert_dup(Key &&key)
Node * get_root_node() const
size_t arena_available_size() const noexcept
Returns the available size in the arena (0 if not using arena)
Hybrid top-down/bottom-up red-black tree with rank support.
Hybrid top-down/bottom-up red-black tree.
Top-down red-black tree with rank (no virtual destructor).
Equality test for containers.
Common methods to the Aleph-w ( ) containers.
and
Conditional mapping of the elements of the container.
Common sequential searching methods on containers.
Node for QuadTree spatial data structure.
QuadTree - Hierarchical spatial index for 2D points.
Mixin that adds STL begin()/end() and cbegin()/cend() to Aleph containers.
__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)
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
size_t compute_cardinality_rec(Node *root) noexcept
Count the number of nodes of a binary tree.
DynSetTree & join(DynSetTree &t, DynSetTree &dup)
Union of two binary search trees.
int preOrderRec(Node *root, void(*visitFct)(Node *, int, int))
Traverse recursively in preorder a binary tree.
Node * find_min(Node *root) noexcept
Return the minimum key contained in a binary search tree.
Node * copyRec(Node *root)
Copy recursively a tree.
bool check_bst(Node *p, const Compare &cmp=Compare())
Return true if p is a binary search tree.
DynSetTree & join_dup(DynSetTree &t)
Union of two binary search trees.
size_t internal_path_length(Node *p) noexcept
Compute the internal path length.
void destroyRec(Node *&root) noexcept
Free recursively all the memory occupied by the tree root
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.
Main namespace for Aleph-w library functions.
bool traverse(Node *root, Op op)
DynSetTree< T > set_unify(const C &c, Op op)
std::decay_t< typename HeadC::Item_Type > T
void callKeyDestructorsRec(Node *&root) noexcept
Traverses recursively the tree and calls key's destructors.
Node * alloc_rval(typename Node::key_type &&key) override
ArenaTreeAllocator(const size_t &sz=1024 *1024)
size_t available_size() const noexcept
ArenaTreeAllocator(const char *base_addr, const size_t &sz)
size_t allocated_size() const noexcept
Node * alloc_lval(const typename Node::key_type &key) override
~ArenaTreeAllocator()=default
void unalloc(Node *p) override
Ranked AVL tree with nodes without a virtual destructor.
AVL binary search tree with nodes without a virtual destructor.
bool operator()(const Container &c1, const Container &c2) const
static constexpr bool has_select
static constexpr bool has_split_pos
static constexpr bool has_find_position
static constexpr bool has_remove_pos
static constexpr bool has_position
const Key & get_curr_ne() const noexcept
typename Tree_Type::Iterator Base
Iterator() noexcept=default
Default constructor creates an "end" iterator.
const Key & get_curr() const
Key & get_curr_ne() noexcept
Node_Op(Key_Op &&__key_op)
Node_Op(Key_Op &__key_op)
void operator()(Node *root)
Randomized binary search tree.
Red-Black binary search tree with nodes without virtual destructor and with subtree counters for sele...
Extended treap (a special type of randomized binary search tree) which manages selection and splittin...
Generic list of items stored in a container.
AVL tree with rank (order statistics).
AVL tree implementation (height-balanced BST).
Utility functions for binary tree operations.
Extended binary node with subtree count.
Generic unbalanced binary search tree.
#define SETTREE_ITOR(Name, Key, Cmp)
Hybrid top-down/bottom-up red-black tree with rank support.
Hybrid top-down/bottom-up red-black tree implementation.
Randomized binary search tree.
Red-Black tree with rank (order statistics).
Red-Black tree implementation (bottom-up balancing).
Top-down splay tree with rank support.
Top-down splay tree implementation (without rank support).
Top-down Red-Black tree with rank support.
Top-down Red-Black tree implementation.
Treap with rank (order statistics).
Treap: randomized BST combining tree and heap properties.