Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_treapRk.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
50# ifndef TPL_TREAPRK_H
51# define TPL_TREAPRK_H
52
53# include <gsl/gsl_rng.h>
54# include <ahFunction.H>
55# include <tpl_binTreeOps.H>
56# include <ran_array.h>
57# include <treapNode.H>
58# include <ah-errors.H>
59
60using namespace Aleph;
61
62namespace Aleph {
63
65{
66 unsigned long priority;
67
68 unsigned long count;
69
70public:
71
73 {
74 /* empty */
75 }
76
81
82 unsigned long & getPriority() noexcept { return priority; }
83
84 unsigned long & getCount() noexcept { return count; }
85
86 void reset() noexcept { count = 1; }
87};
88
90
179 template <template <class> class NodeType, class Key, class Compare>
181{
182public:
183
185
186private:
187
192 Compare cmp;
193
194 void init(unsigned int seed)
195 {
198
199 ah_bad_alloc_if(r == nullptr);
200
201 gsl_rng_set(r, seed % gsl_rng_max(r));
202 }
203
204public:
205
207 void set_seed(const unsigned long seed) noexcept { gsl_rng_set(r, seed); }
208
210 Compare & key_comp() noexcept { return cmp; }
211
213 Compare & get_compare() noexcept { return key_comp(); }
214
217 Gen_Treap_Rk(const unsigned long seed, Compare __cmp = Compare())
219 {
220 init(seed);
221 }
222
224 {
225 // empty
226 }
227
229 {
230 if (r != nullptr)
232 }
233
235 void swap(Gen_Treap_Rk & tree) noexcept
236 {
237 std::swap(tree_root, tree.tree_root);
238 std::swap(cmp, tree.cmp);
239 std::swap(r, tree.r);
240 }
241
244
246
253 Node * search(const Key & key) const noexcept
254 {
256 return ret_val == Node::NullPtr ? nullptr : ret_val;
257 }
258
259private:
260
261 bool insert(Node *& root, Node * p) noexcept
262 {
263 if (root == Node::NullPtr)
264 {
265 root = p;
266 return true;
267 }
268
269 const Key & pk = KEY(p);
270 const Key & rk = KEY(root);
271 if (cmp(pk, rk))
272 {
273 if (insert(LLINK(root), p))
274 {
275 ++COUNT(root);
276 if (PRIO(LLINK(root)) < PRIO(root) )
278
279 return true;
280 }
281 }
282 else if (cmp(rk, pk))
283 {
284 if (insert(RLINK(root), p))
285 {
286 ++COUNT(root);
287 if (PRIO(RLINK(root)) < PRIO(root) )
289
290 return true;
291 }
292 }
293
294 return false;
295 }
296
297 // Search or insert p. Return p if KEY(p) is not in the tree;
298 // otherwise, it returns a pointer to a node containing KEY(p)
299 Node * search_or_insert(Node *& root, Node * p) noexcept
300 {
301 if (root == Node::NullPtr)
302 return root = p;
303
304 const Key & pk = KEY(p);
305 const Key & rk = KEY(root);
306 if (cmp(pk, rk))
307 {
309 if (ret == p) // insertion done?
310 { // yes ==> increase counter and perhaps rotate
311 ++COUNT(root);
312 if (PRIO(LLINK(root)) < PRIO(root))
314
316 PRIO(root) <= PRIO(LLINK(root)));
317 }
318
319 return ret;
320 }
321 if (cmp(rk, pk))
322 {
324 if (ret == p) // insertion done?
325 { // yes ==> increase counter and perhaps rotate
326 ++COUNT(root);
327 if (PRIO(RLINK(root)) < PRIO(root))
329
331 PRIO(root) <= PRIO(LLINK(root)));
332 }
333
334 return ret;
335 }
336
338
339 return root;
340 }
341
342 // Return p; root could be modified
343 Node * insert_dup(Node *& root, Node * p) noexcept
344 {
345 if (root == Node::NullPtr)
346 return root = p;
347
348 const Key & pk = KEY(p);
349 const Key & rk = KEY(root);
350 if (cmp(pk, rk))
351 {
352 insert_dup(LLINK(root), p);
353 ++COUNT(root);
354 if (PRIO(LLINK(root)) < PRIO(root))
356 }
357 else
358 {
359 insert_dup(RLINK(root), p);
360 ++COUNT(root);
361 if (PRIO(RLINK(root)) < PRIO(root))
363 }
364
365 return p;
366 }
367
368public:
369
379 Node * insert(Node * p) noexcept
380 {
381 assert(p != Node::NullPtr);
382
383 PRIO(p) = gsl_rng_get(r);
384
385 return insert(tree_root, p) ? p : nullptr;
386 }
387
395 Node * insert_dup(Node * p) noexcept
396 {
397 assert(p != Node::NullPtr);
398
399 PRIO(p) = gsl_rng_get(r);
400
401 return insert_dup(tree_root, p);
402 }
403
416 Node * search_or_insert(Node * p) noexcept
417 {
418 assert(p != Node::NullPtr);
419
420 PRIO(p) = gsl_rng_get(r);
421
422 return search_or_insert(tree_root, p);
423 }
424
426 bool verify() const { return is_treap(tree_root); }
427
428private:
429
430 static Node * join_exclusive(Node * t1, Node * t2) noexcept
431 {
432 if (t1 == Node::NullPtr)
433 return t2;
434
435 if (t2 == Node::NullPtr)
436 return t1;
437
438 if (PRIO(t1) < PRIO(t2))
439 {
440 COUNT(t1) += COUNT(t2);
442 return t1;
443 }
444 COUNT(t2) += COUNT(t1);
446 return t2;
447 }
448
449 Node * remove(Node *& root, const Key & key) noexcept
450 {
451 if (root == Node::NullPtr)
452 return Node::NullPtr;
453
454 Node * ret_val;
455 const Key & rk = KEY(root);
456 if (cmp(key, rk))
457 ret_val = remove(LLINK(root), key);
458 else if (cmp(rk, key))
459 ret_val = remove(RLINK(root), key);
460 else
461 {
462 ret_val = root;
464
465 return ret_val;
466 }
467
468 if (ret_val == Node::NullPtr)
469 return Node::NullPtr;
470
471 --COUNT(root);
472
473 return ret_val;
474 }
475
476public:
477
484 Node * remove(const Key & key) noexcept
485 {
486 Node * ret_val = remove(tree_root, key);
487 if (ret_val == Node::NullPtr)
488 return nullptr;
489
490 ret_val->reset();
491
492 return ret_val;
493 }
494
503 Node * remove(const size_t beg, const size_t end)
504 {
505 ah_range_error_if(beg > end or end > COUNT(tree_root)) << "remove of TreapRk out of range";
506
507 Node * before_beg, * after_end, * aux;
508
510
511 split_pos_rec(ret_val, end + 1, aux, after_end);
513
515
516 return ret_val;
517 }
518
519private:
520
521 static Node * remove_pos(Node *& root, const size_t pos) noexcept
522 {
523 if (pos == COUNT(LLINK(root)))
524 {
525 Node * ret_val = root;
527 return ret_val;
528 }
529
530 --COUNT(root);
531 if (pos < COUNT(LLINK(root)))
532 return remove_pos(LLINK(root), pos);
533 return remove_pos(RLINK(root), pos - COUNT(LLINK(root)) - 1);
534 }
535
536public:
537
545 Node * remove_pos(const size_t pos)
546 {
547 ah_out_of_range_error_if(pos >= COUNT(tree_root)) << "infix position out of range";
548
549 return remove_pos(tree_root, pos);
550 }
551
559 Node * select(const size_t i) const
560 {
561 return Aleph::select(tree_root, i);
562 }
563
565 size_t size() const noexcept { return COUNT(tree_root); }
566
568 bool is_empty() const noexcept { return tree_root == Node::NullPtr; }
569
578 std::pair<int, Node*> position(const Key & key) const noexcept
579 {
580 std::pair<int, Node*> ret_val;
581
583 inorder_position(tree_root, key, ret_val.second);
584
585 return ret_val;
586 }
587
614 std::pair<int, Node*> find_position(const Key & key) const noexcept
615 {
616 std::pair<int, Node*> r(-2, nullptr);
617
619 find_position(tree_root, key, r.second);
620
621 return r;
622 }
623
632 bool split_key(const Key & key, Gen_Treap_Rk & t1, Gen_Treap_Rk & t2) noexcept
633 {
634 return split_key_rec_xt(tree_root, key, t1.getRoot(), t2.getRoot());
635 }
636
647 void
648 split_key_dup(const Key & key, Gen_Treap_Rk & t1, Gen_Treap_Rk & t2) noexcept
649 {
650 split_key_dup_rec_xt(tree_root, key, t1.getRoot(), t2.getRoot());
651 }
652
659 void split_pos(size_t pos, Gen_Treap_Rk & t1, Gen_Treap_Rk & t2)
660 {
661 split_pos_rec(tree_root, pos, t1.getRoot(), t2.getRoot());
662 }
663
664private:
665
666 void join_dup(Node *& t1, Node * t2) noexcept
667 {
668 if (t2 == Node::NullPtr)
669 return;
670
671 Node * l = LLINK(t2), * r = RLINK(t2);
672 t2->reset();
673 insert_dup(t1, t2); // insert_dup modifies t1 by reference
674 join_dup(t1, l);
675 join_dup(t1, r);
676 }
677
678 void join(Node *& t1, Node * t2, Node *& dup) noexcept
679 {
680 if (t2 == Node::NullPtr)
681 return;
682
683 Node * l = LLINK(t2), * r = RLINK(t2);
684 t2->reset();
685 ins:
686 const bool inserted = insert(t1, t2);
687 if (not inserted)
688 {
689 Node * removed = remove(t1, KEY(t2));
690 removed->reset();
691 insert_dup(dup, removed);
692 goto ins;
693 }
694 join(t1, l, dup);
695 join(t1, r, dup);
696 }
697
698public:
699
712 void join(Gen_Treap_Rk & t, Gen_Treap_Rk & dup) noexcept
713 {
714 join(tree_root, t.tree_root, dup.tree_root);
715 t.tree_root = Node::NullPtr;
716 }
717
726 void join_dup(Gen_Treap_Rk & t) noexcept
727 {
728 join_dup(tree_root, t.tree_root);
729 t.tree_root = Node::NullPtr;
730 }
731
743 void join_exclusive(Gen_Treap_Rk & t) noexcept
744 {
745 tree_root = join_exclusive(tree_root, t.tree_root);
746 t.tree_root = Node::NullPtr;
747 }
748
756 {
757 protected:
758
760 mutable Node * curr;
761 mutable int curr_pos;
762
763 static constexpr int Pos_Not_Current = -1;
764 static constexpr int Pos_Empty_Container = -2;
765 static constexpr int Pos_Not_Updated = -3;
766
767 private:
768
770 {
771 return COUNT(tree_ptr->getRoot()) == 0;
772 }
773
775 {
776 return curr_pos != Pos_Not_Updated;
777 }
778
780 {
781 return curr != nullptr;
782 }
783
785 {
786 return pos_updated() and curr_updated();
787 }
788
796
807
808 public:
809
811 : tree_ptr(nullptr), curr(nullptr), curr_pos(Pos_Not_Current)
812 {
813 /* empty */
814 }
815
818 : tree_ptr(&const_cast<Gen_Treap_Rk&>(__tree)), curr(nullptr)
819 {
821 }
822
825 : tree_ptr(&const_cast<Gen_Treap_Rk&>(__tree)),
827 {
828 // empty
829 }
830
832 Iterator(const Gen_Treap_Rk & __tree, const size_t pos) noexcept
833 : tree_ptr(&const_cast<Gen_Treap_Rk&>(__tree)),
834 curr(nullptr), curr_pos(pos)
835 {
836 // empty
837 }
838
840 : tree_ptr(itor.tree_ptr), curr(itor.curr), curr_pos(itor.curr_pos)
841 {
842 // Empty
843 }
844
845 Iterator & operator = (const Iterator & itor) noexcept
846 {
847 if (this == &itor)
848 return *this;
849
850 tree_ptr = itor.tree_ptr;
851 curr = itor.curr;
852 curr_pos = itor.curr_pos;
853
854 return *this;
855 }
856
859 {
860 curr = nullptr;
862 }
863
866 {
867 curr = nullptr;
869 COUNT(tree_ptr->getRoot()) - 1);
870 }
871
874 {
875 put_itor_at_the_end(*this);
876 }
877
885 void reset_to_key(const Key & key) noexcept
886 {
887 std::pair<int, Node*> p = tree_ptr->find_position(key);
888 curr_pos = p.first;
889 }
890
896 void reset_to_node(Node * node) noexcept
897 {
898 curr = node;
899 curr_pos = -2;
900 }
901
903 void reset_to_pos(const size_t pos) noexcept
904 {
905 curr = nullptr;
906 curr_pos = pos;
907 }
908
911 {
912 if (not curr_updated())
913 update_curr();
914
915 return curr;
916 }
917
920 {
921 return get_curr_ne();
922 }
923
932 size_t get_current_position() const
933 {
934 if (not pos_updated())
935 update_pos();
936
937 ah_range_error_if(curr_pos < -1) << "TreapRk iterator has not current";
938
939 ah_range_error_if(curr_pos > COUNT(tree_ptr->getRoot())) << "TreapRk iterator has not current";
940
941 return curr_pos;
942 }
943
945 size_t get_pos() const { return get_current_position(); }
946
949 {
950 if (not pos_updated())
951 update_pos();
952
953 return curr_pos >= 0 and curr_pos < COUNT(tree_ptr->getRoot());
954 }
955
958 void prev()
959 {
960 ah_underflow_error_if(not has_curr()) << "TreapRk iterator has not current";
961
962 --curr_pos;
963 curr = nullptr;
964 }
965
967 {
968 ++curr_pos;
969 curr = nullptr;
970 }
971
974 void next()
975 {
976 ah_underflow_error_if(not has_curr()) << "TreapRk iterator has not current";
977 next_ne();
978 }
979
982 {
983 ah_underflow_error_if(not has_curr()) << "TreapRk iterator has not current";
984
985 if (not curr_updated())
986 update_curr();
987
989
990 curr = nullptr;
991
992 return ret_val;
993 }
994
996 bool operator == (const Iterator & itor) const noexcept
997 {
998 if (is_container_empty() and itor.is_container_empty())
999 return true;
1000
1001 if (pos_updated() and itor.pos_updated())
1002 return curr_pos == itor.curr_pos;
1003
1004 if (curr_updated() and itor.curr_updated())
1005 return curr == itor.curr;
1006
1007 if (not pos_updated())
1008 {
1009 update_pos();
1010 return curr_pos == itor.curr_pos;
1011 }
1012
1013 itor.update_pos();
1014
1015 return curr_pos == itor.curr_pos;
1016 }
1017
1019 bool operator != (const Iterator & itor) const
1020 {
1021 return not (*this == itor);
1022 }
1023
1024 bool verify(Gen_Treap_Rk * r) const noexcept
1025 {
1026 return tree_ptr->getRoot() == r->getRoot();
1027 }
1028
1029 bool verify(const Iterator & it) const noexcept
1030 {
1031 return tree_ptr->getRoot() == it.tree_ptr->getRoot();
1032 }
1033 }; // end class Iterator
1034};
1035
1075 template <typename Key, class Compare = Aleph::less<Key>>
1076struct Treap_Rk : public Gen_Treap_Rk<Treap_Rk_Node, Key, Compare>
1077{
1079 using Base::Base;
1080};
1081
1121 template <typename Key, class Compare = Aleph::less<Key>>
1122struct Treap_Rk_Vtl : public Gen_Treap_Rk<Treap_Rk_NodeVtl, Key, Compare>
1123{
1125 using Base::Base;
1126};
1127
1128
1129} // end namespace Aleph
1130
1131# endif // TPL_TREAPRK_H
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:579
#define ah_underflow_error_if(C)
Throws std::underflow_error if condition holds.
Definition ah-errors.H:368
#define ah_bad_alloc_if(C)
Throws std::bad_alloc if condition holds.
Definition ah-errors.H:429
#define ah_range_error_if(C)
Throws std::range_error if condition holds.
Definition ah-errors.H:207
SentinelCtor
Tag type for sentinel node construction.
Definition ahDefs.H:81
Standard functor implementations and comparison objects.
void put_itor_at_the_end(Itor &it) noexcept
Definition aleph.H:54
@ KEY
Definition btreepic.C:169
Iterator on nodes of the tree.
bool operator==(const Iterator &itor) const noexcept
Return true if this is equal to itor
bool has_curr() const noexcept
Return true if iterator has current node.
static constexpr int Pos_Not_Updated
void update_curr() const noexcept
Node * del()
Remove the current node and move the iterator one position forward.
void reset_to_key(const Key &key) noexcept
Put the iterator to a node according to specific key.
Node * get_curr() const noexcept
void reset_first() noexcept
Reset the iterator to the first position.
Iterator & operator=(const Iterator &itor) noexcept
Iterator(const Gen_Treap_Rk &__tree, const size_t pos) noexcept
Initialize an iterator starting from the iorder position pos
bool curr_updated() const noexcept
bool verify(const Iterator &it) const noexcept
static constexpr int Pos_Empty_Container
bool operator!=(const Iterator &itor) const
Return true if this is not equal to itor
Node * get_curr_ne() const noexcept
Return the current node.
void prev()
Move the iterator one position backward.
void update_pos() const noexcept
Iterator(const Gen_Treap_Rk &__tree) noexcept
Initialize an iterator on __tree
void reset_last() noexcept
Reset the iterator to the last position.
void reset_to_pos(const size_t pos) noexcept
Put the current to the position pos.
bool verify(Gen_Treap_Rk *r) const noexcept
void next()
Move the iterator one position forward.
bool is_container_empty() const noexcept
static constexpr int Pos_Not_Current
void reset_to_node(Node *node) noexcept
Put the current node to a specific node.
Iterator(const Iterator &itor) noexcept
Iterator(const Gen_Treap_Rk &__tree, Node *__curr) noexcept
Initialize an iterator starting from node __curr
size_t get_current_position() const
return the position of current node
bool pos_updated() const noexcept
void end() noexcept
Put the iterator in the end state.
bool is_updated() const noexcept
Extended Treap with rank support for O(log n) indexed access.
Gen_Treap_Rk(Compare __cmp=Compare())
Gen_Treap_Rk(const unsigned long seed, Compare __cmp=Compare())
Initialize a treap with random seed and comparison criteria __cmp
Node head
The type of node.
Node * remove(const Key &key) noexcept
Remove a key from the tree.
void set_seed(const unsigned long seed) noexcept
Set the random number generator seed.
bool split_key(const Key &key, Gen_Treap_Rk &t1, Gen_Treap_Rk &t2) noexcept
Split the tree according to a key.
Node *& getRoot() noexcept
Return the tree's root.
static Node * remove_pos(Node *&root, const size_t pos) noexcept
bool verify() const
Return true if the treap is consistent.
Compare & get_compare() noexcept
Node * insert_dup(Node *&root, Node *p) noexcept
Node * select(const size_t i) const
Return the i-th node in order sense.
Node * insert(Node *p) noexcept
Insert a node in a treap.
void join_exclusive(Gen_Treap_Rk &t) noexcept
Join exclusive of this with t
size_t size() const noexcept
Return the number of nodes contained in the tree.
NodeType< Key > Node
static Node * join_exclusive(Node *t1, Node *t2) noexcept
void join_dup(Node *&t1, Node *t2) noexcept
Node * insert_dup(Node *p) noexcept
Insert a node in the tree.
void split_pos(size_t pos, Gen_Treap_Rk &t1, Gen_Treap_Rk &t2)
Split the tree at the inorder position pos.
Node * remove(const size_t beg, const size_t end)
Remove from the treap all the keys between inorder position beg and end.
Node * search_or_insert(Node *&root, Node *p) noexcept
Node * search(const Key &key) const noexcept
Search a key in a treap.
Node * search_or_insert(Node *p) noexcept
Search or insert a key.
void join(Node *&t1, Node *t2, Node *&dup) noexcept
void init(unsigned int seed)
Node * remove_pos(const size_t pos)
Remove the node at the inorder position pos.
std::pair< int, Node * > find_position(const Key &key) const noexcept
Find the inorder position of a key in the tree.
Node * remove(Node *&root, const Key &key) noexcept
Node * getRoot() const noexcept
Compare & key_comp() noexcept
return the comparison criteria
void swap(Gen_Treap_Rk &tree) noexcept
Swap in constant time all the nodes of this with tree
void join_dup(Gen_Treap_Rk &t) noexcept
Join this with t independently of the presence of duplicated keys.
void join(Gen_Treap_Rk &t, Gen_Treap_Rk &dup) noexcept
Join this with t filtering the duplicated keys.
bool is_empty() const noexcept
Return true if tree is empty.
bool insert(Node *&root, Node *p) noexcept
void split_key_dup(const Key &key, Gen_Treap_Rk &t1, Gen_Treap_Rk &t2) noexcept
Split the tree according to a key that could be in the tree.
void reset() noexcept
Definition htlist.H:516
void reset() noexcept
Definition tpl_treapRk.H:86
TreapRkNode_Data() noexcept
Definition tpl_treapRk.H:72
unsigned long priority
Definition tpl_treapRk.H:66
unsigned long & getPriority() noexcept
Definition tpl_treapRk.H:82
unsigned long & getCount() noexcept
Definition tpl_treapRk.H:84
TreapRkNode_Data(SentinelCtor) noexcept
Definition tpl_treapRk.H:77
__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)
Definition gmpfrxx.h:4060
long inorder_position(Node *r, const typename Node::key_type &key, Node *&p, Compare &cmp) noexcept
Compute the inorder position of a key.
void split_pos_rec(Node *&r, const size_t i, Node *&ts, Node *&tg)
Split a extended binary tree according to a position.
std::pair< int, Node * > position(const Key &key) const noexcept
Compute the inorder position of a key.
#define DECLARE_BINNODE_SENTINEL(Name, height, Control_Data)
Specify tree node for a binary tree.
constexpr Node *& RLINK(Node *p) noexcept
Return the right tree of p.
auto & COUNT(Node *p) noexcept
Return the number of nodes of the tree fron p is root.
Node * rotate_to_left_xt(Node *p) noexcept
Rotate to left the extended binary tree with root p.
bool split_key_rec_xt(Node *&root, const typename Node::key_type &key, Node *&l, Node *&r, Compare &cmp) noexcept
Split an extended binary search tree according to a key.
Node * select(Node *r, const size_t pos)
Iterative selection of a node according to inorder position.
Node * searchInBinTree(Node *root, const typename Node::key_type &key, const Compare &cmp=Compare()) noexcept
Search a key in a binary search tree.
unsigned long & PRIO(Node *p) noexcept
Access the priority of a treap node.
Definition treapNode.H:120
constexpr Node *& LLINK(Node *p) noexcept
Return a pointer to left subtree.
Node * rotate_to_right_xt(Node *p) noexcept
Rotate to right the extended bianry tree with root p
void split_key_dup_rec_xt(Node *&root, const typename Node::key_type &key, Node *&l, Node *&r, Compare &cmp) noexcept
Split an extended binary search tree according to a key which can be in the tree.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
bool is_treap(Node *root) noexcept
Validate that a tree satisfies treap (heap) property.
Definition treapNode.H:144
const long Max_Priority
Maximum priority value (used for sentinel/leaves)
Definition treapNode.H:75
static bool init
Definition hash-fct.C:47
const long Min_Priority
Minimum priority value.
Definition treapNode.H:78
DynList< T > maps(const C &c, Op op)
Classic map operation.
Extended treap (a special type of randomized binary search tree) which manages selection and splittin...
Extended treap (a special type of randomized binary search tree) which manages selection and splittin...
Binary tree operations (split, join, rotate).
Treap node definition with BST key and heap priority.
DynList< int > l