Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_treap.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
52# ifndef TPL_TREAP_H
53# define TPL_TREAP_H
54
55# include <gsl/gsl_rng.h>
56# include <ahFunction.H>
57# include <tpl_binNodeUtils.H>
58# include <treapNode.H>
59# include <tpl_binTreeOps.H>
60# include <ah-errors.H>
61
62using namespace Aleph;
63
64namespace Aleph
65{
146 template <template <typename> class NodeType, typename Key, class Compare>
148 {
149 public:
151
152 private:
157 Compare cmp;
158
159 void init(const unsigned int seed)
160 {
163
164 ah_bad_alloc_if(r == nullptr);
165
166 gsl_rng_set(r, seed % gsl_rng_max(r));
167 }
168
169 public:
171 void set_seed(const unsigned long seed) noexcept { gsl_rng_set(r, seed); }
172
174 void swap(Gen_Treap & tree) noexcept
175 {
176 std::swap(tree_root, tree.tree_root);
177 std::swap(cmp, tree.cmp);
178 std::swap(r, tree.r);
179 }
180
182 Compare &key_comp() noexcept { return cmp; }
183
185 Compare &get_compare() noexcept { return key_comp(); }
186
189 Gen_Treap(const unsigned long seed, const Compare & __cmp = Compare())
191 {
192 init(seed);
193 }
194
197 Gen_Treap(const Compare & cmp = Compare())
199 { /* empty */
200 }
201
203 {
204 if (r != nullptr)
206 }
207
210
213
220 Node * search(const Key & key) const noexcept
221 {
223 return ret_val == Node::NullPtr ? nullptr : ret_val;
224 }
225
226 private:
227 Node * insert(Node *root, Node *p) noexcept
228 {
229 if (root == Node::NullPtr)
230 return p;
231
232 const Key & pk = KEY(p);
233 const Key & rk = KEY(root);
234 Node *insertion_result = nullptr;
235 if (cmp(pk, rk))
236 {
238 if (insertion_result == Node::NullPtr)
239 return Node::NullPtr;
240
243 return rotate_to_right(root);
244 return root;
245 }
246 if (cmp(rk, pk))
247 {
249 if (insertion_result == Node::NullPtr)
250 return Node::NullPtr;
251
254 return rotate_to_left(root);
255 return root;
256 }
257
258 return Node::NullPtr;
259 }
260
261 Node * search_or_insert(Node *& root, Node *p) noexcept
262 {
263 if (root == Node::NullPtr)
264 return root = p;
265
266 const Key & pk = KEY(p);
267 const Key & rk = KEY(root);
268 if (cmp(pk, rk))
269 {
271 if (ret == p) // p was inserted?
272 if (PRIO(LLINK(root)) < PRIO(root))
274
275 return ret;
276 }
277 if (cmp(rk, pk))
278 {
280 if (ret == p) // p was inserted?
281 if (PRIO(RLINK(root)) < PRIO(root))
283
284 return ret;
285 }
286
287 return root;
288 }
289
290 Node * insert_dup(Node *root, Node *p) noexcept
291 {
292 if (root == Node::NullPtr)
293 return p;
294
295 const Key & pk = KEY(p);
296 const Key & rk = KEY(root);
297 if (cmp(pk, rk))
298 {
299 if (Node *result = LLINK(root) = insert_dup(LLINK(root), p); PRIO(result) < PRIO(root))
300 return rotate_to_right(root);
301 return root;
302 }
303 if (Node *result = RLINK(root) = insert_dup(RLINK(root), p); PRIO(result) < PRIO(root))
304 return rotate_to_left(root);
305 return root;
306 }
307
308 public:
318 Node * insert(Node *p) noexcept
319 {
320 assert(p != Node::NullPtr);
321
322 PRIO(p) = gsl_rng_get(r); // Priority Random Selection
323 Node *result = insert(tree_root, p);
324 if (result == Node::NullPtr)
325 return nullptr;
326
327 tree_root = result;
328
329 return p;
330 }
331
345 {
346 assert(p != Node::NullPtr);
347
348 PRIO(p) = gsl_rng_get(r); // Priority Random Selection
349
350 return search_or_insert(tree_root, p);
351 }
352
360 Node * insert_dup(Node *p) noexcept
361 {
362 assert(p != Node::NullPtr);
363
364 PRIO(p) = gsl_rng_get(r); // Priority Random Selection
366
367 return p;
368 }
369
372
379 Node * remove(const Key & key) noexcept
380 {
381 Node **pp = &RLINK(head_ptr);
382 Node *p = tree_root;
383
384 while (p != Node::NullPtr) // descender buscando la clave
385 {
386 const Key & pk = KEY(p);
387 if (cmp(key, pk))
388 {
389 pp = &LLINK(p);
390 p = LLINK(p);
391 }
392 else if (cmp(pk, key))
393 {
394 pp = &RLINK(p);
395 p = RLINK(p);
396 }
397 else
398 break; //found!
399 }
400
401 if (p == Node::NullPtr)
402 return nullptr; // Key was not found
403
404 // rotate p until it becomes a leaf
405 while (not (LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr))
406 if (PRIO(LLINK(p)) < PRIO(RLINK(p)))
407 {
408 *pp = rotate_to_right(p);
409 pp = &RLINK(*pp);
410 }
411 else
412 {
413 *pp = rotate_to_left(p);
414 pp = &LLINK(*pp);
415 }
416
417 *pp = Node::NullPtr;
418
419 p->reset();
420
421 return p;
422 }
423
424 private:
425 static Node * join_exclusive(Node *t1, Node *t2) noexcept
426 {
427 if (t1 == Node::NullPtr)
428 return t2;
429
430 if (t2 == Node::NullPtr)
431 return t1;
432
433 if (PRIO(t1) < PRIO(t2))
434 {
436 return t1;
437 }
439 return t2;
440 }
441
442 Node * remove(Node *& root, const Key & key) noexcept
443 {
444 if (root == Node::NullPtr)
445 return Node::NullPtr;
446
447 const Key & rk = KEY(root);
448 if (cmp(key, rk))
449 return remove(LLINK(root), key);
450 if (cmp(rk, key))
451 return remove(RLINK(root), key);
452
453 Node *ret = root; // key found!
455 ret->reset();
456
457 return ret;
458 }
459
460 void join_dup(Node *& t1, Node *t2) noexcept
461 {
462 if (t2 == Node::NullPtr)
463 return;
464
465 Node *l = LLINK(t2), *r = RLINK(t2);
466 t2->reset();
467 t1 = insert_dup(t1, t2);
468 join_dup(t1, l);
469 join_dup(t1, r);
470 }
471
472 void join(Node *& t1, Node *t2, Node *& dup) noexcept
473 {
474 if (t2 == Node::NullPtr)
475 return;
476
477 Node *l = LLINK(t2), *r = RLINK(t2);
478 t2->reset();
479 ins:
480 Node *ret = insert(t1, t2);
481 if (ret == Node::NullPtr)
482 {
483 dup = insert_dup(dup, remove(t1, KEY(t2)));
484 goto ins;
485 }
486
487 t1 = ret;
488 join(t1, l, dup);
489 join(t1, r, dup);
490 }
491
492 public:
505 void join(Gen_Treap & t, Gen_Treap & dup) noexcept
506 {
507 join(tree_root, t.tree_root, dup.tree_root);
508 t.tree_root = Node::NullPtr;
509 }
510
519 void join_dup(Gen_Treap & t) noexcept
520 {
521 join_dup(tree_root, t.tree_root);
522 t.tree_root = Node::NullPtr;
523 }
524
536 void join_exclusive(Gen_Treap & t) noexcept
537 {
538 tree_root = join_exclusive(tree_root, t.tree_root);
539 t.tree_root = Node::NullPtr;
540 }
541
550 bool split_key(const Key & key, Gen_Treap & t1, Gen_Treap & t2)
551 {
552 return split_key_rec(tree_root, key, t1.getRoot(), t2.getRoot());
553 }
554
565 void split_key_dup(const Key & key, Gen_Treap & t1, Gen_Treap & t2)
566 {
567 split_key_dup_rec(tree_root, key, t1.getRoot(), t2.getRoot());
568 }
569
582 };
583
609 template <typename Key, class Compare = Aleph::less<Key>>
610 struct Treap : public Gen_Treap<TreapNode, Key, Compare>
611 {
613 using Base::Base;
614 };
615
616
642 template <typename Key, class Compare = Aleph::less<Key>>
643 struct Treap_Vtl : public Gen_Treap<TreapNodeVtl, Key, Compare>
644 {
646 using Base::Base;
647 };
648} // end namespace Aleph
649# endif // TPL_TREAP_H
Exception handling system with formatted messages for Aleph-w.
#define ah_bad_alloc_if(C)
Throws std::bad_alloc if condition holds.
Definition ah-errors.H:429
Standard functor implementations and comparison objects.
@ KEY
Definition btreepic.C:169
Inorder iterator on the nodes of a binary tree.
Treap - A randomized binary search tree using heap-ordered priorities.
Definition tpl_treap.H:148
Node * insert(Node *p) noexcept
Insert a node in a treap.
Definition tpl_treap.H:318
void set_seed(const unsigned long seed) noexcept
Set the random number generator seed.
Definition tpl_treap.H:171
Node * remove(const Key &key) noexcept
Remove a key from the tree.
Definition tpl_treap.H:379
bool verify() const noexcept
Return true if this is a consistent treap.
Definition tpl_treap.H:371
Gen_Treap(const unsigned long seed, const Compare &__cmp=Compare())
Initialize a treap with random seed and comparison criteria __cmp
Definition tpl_treap.H:189
void split_key_dup(const Key &key, Gen_Treap &t1, Gen_Treap &t2)
Split the tree according to a key that could be in the tree.
Definition tpl_treap.H:565
Node * search(const Key &key) const noexcept
Search a key in a treap.
Definition tpl_treap.H:220
NodeType< Key > Node
Definition tpl_treap.H:150
Node * insert_dup(Node *root, Node *p) noexcept
Definition tpl_treap.H:290
Node *& getRoot() noexcept
Return the tree's root.
Definition tpl_treap.H:212
void join_dup(Node *&t1, Node *t2) noexcept
Definition tpl_treap.H:460
void swap(Gen_Treap &tree) noexcept
Swap in constant time all the nodes of this with tree
Definition tpl_treap.H:174
void join(Gen_Treap &t, Gen_Treap &dup) noexcept
Join this with t filtering the duplicated keys.
Definition tpl_treap.H:505
void init(const unsigned int seed)
Definition tpl_treap.H:159
Compare & key_comp() noexcept
return the comparison criteria
Definition tpl_treap.H:182
Gen_Treap(const Compare &cmp=Compare())
Initialize a treap with random seed from system time and comparison criteria cmp
Definition tpl_treap.H:197
Node *& tree_root
Definition tpl_treap.H:155
Node * search_or_insert(Node *&root, Node *p) noexcept
Definition tpl_treap.H:261
Node * search_or_insert(Node *p) noexcept
Search or insert a key.
Definition tpl_treap.H:344
Node * insert_dup(Node *p) noexcept
Insert a node in the tree.
Definition tpl_treap.H:360
Compare & get_compare() noexcept
Definition tpl_treap.H:185
Node head
The type of node.
Definition tpl_treap.H:153
static Node * join_exclusive(Node *t1, Node *t2) noexcept
Definition tpl_treap.H:425
void join(Node *&t1, Node *t2, Node *&dup) noexcept
Definition tpl_treap.H:472
bool split_key(const Key &key, Gen_Treap &t1, Gen_Treap &t2)
Split the tree according to a key.
Definition tpl_treap.H:550
Node * remove(Node *&root, const Key &key) noexcept
Definition tpl_treap.H:442
void join_dup(Gen_Treap &t) noexcept
Join this with t independently of the presence of duplicated keys.
Definition tpl_treap.H:519
gsl_rng * gsl_rng_object() noexcept
Get a pointer to gsl random number generator.
Definition tpl_treap.H:209
void join_exclusive(Gen_Treap &t) noexcept
Join exclusive of this with t
Definition tpl_treap.H:536
Node * insert(Node *root, Node *p) noexcept
Definition tpl_treap.H:227
void reset() noexcept
Definition htlist.H:516
__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
Node * rotate_to_left(Node *p) noexcept
Rotate to the left the tree with root p
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.
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.
constexpr Node *& RLINK(Node *p) noexcept
Return the right tree of p.
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.
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
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.
Iterator on nodes of the tree.
Definition tpl_treap.H:577
Iterator() noexcept=default
Default constructor creates an "end" iterator.
Treap (a special type of randomized binary search tree) using nodes with virtual destructors.
Definition tpl_treap.H:644
Treap (a special type of randomized binary search tree) using nodes without virtual destructor.
Definition tpl_treap.H:611
Utility functions for binary tree operations.
Binary tree operations (split, join, rotate).
Treap node definition with BST key and heap priority.
DynList< int > l