Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_splay_tree.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
46# ifndef TPL_SPLAY_TREE_H
47# define TPL_SPLAY_TREE_H
48
49# include <tpl_binNode.H>
50# include <tpl_binNodeUtils.H>
51# include <ah-concepts.H>
52
53using namespace Aleph;
54
55
134template <template <class> class NodeType, typename Key, class Compare>
137{
138public:
140
141private:
144 Compare cmp;
145 static constexpr signed char CmpLess = -1;
146 static constexpr signed char CmpEqual = 0;
147 static constexpr signed char CmpGreater = 1;
148
149 signed char splay_impl(const Key & key) noexcept
150 {
151 Node headNode;
152 Node *l = &headNode;
153 Node *r = &headNode;
154 Node *t = root;
155 signed char cmp_result = CmpEqual;
156
157 while (true)
158 {
159 if (const Key & tk = KEY(t); cmp(key, tk)) // key < tk: go left
160 {
162 if (LLINK(t) == Node::NullPtr) [[unlikely]]
163 break;
164
165 if (cmp(key, KEY(LLINK(t)))) // zig-zig case
166 {
167 t = rotate_to_right(t);
168 if (LLINK(t) == Node::NullPtr) [[unlikely]]
169 break;
170 }
171
172 LLINK(r) = t;
173 r = t;
174 t = LLINK(t);
175 }
176 else if (cmp(tk, key)) // tk < key: go right
177 {
179 if (RLINK(t) == Node::NullPtr) [[unlikely]]
180 break;
181
182 if (cmp(KEY(RLINK(t)), key)) // zig-zig case
183 {
184 t = rotate_to_left(t);
185 if (RLINK(t) == Node::NullPtr) [[unlikely]]
186 break;
187 }
188
189 RLINK(l) = t;
190 l = t;
191 t = RLINK(t);
192 }
193 else [[unlikely]] // key == tk: found
194 {
196 break;
197 }
198 }
199
200 /* reassembling of subtrees in one with current as root */
201 RLINK(l) = LLINK(t);
202 LLINK(r) = RLINK(t);
203 LLINK(t) = headNode.getR();
204 RLINK(t) = headNode.getL();
205
206 root = t;
207
208 return cmp_result;
209 }
210
211public:
213 using key_type = Key;
214
216 Compare &key_comp() noexcept { return cmp; }
217
219 Compare &get_compare() noexcept { return key_comp(); }
220
223 void splay(const Key & key) noexcept
224 {
225 (void) splay_impl(key);
226 }
227
229 GenTdSplayTree(Compare __cmp = Compare()) noexcept
230 : head(&headnode), root(headnode.getR()), cmp(__cmp)
231 {
232 // Empty
233 }
234
235 void swap(GenTdSplayTree & tree) noexcept
236 {
237 std::swap(root, tree.root);
238 std::swap(cmp, tree.cmp);
239 }
240
242 virtual ~GenTdSplayTree() = default;
243
244private:
245 Node * __insert(Node *p) noexcept
246 {
247 const Key & pk = KEY(p);
248 const Key & rk = KEY(root);
249 if (cmp(pk, rk))
250 { /* root is predecessor of p */
251 LLINK(p) = LLINK(root);
252 RLINK(p) = root;
253 LLINK(root) = Node::NullPtr;
254 }
255 else
256 { /* root is successor of p */
257 RLINK(p) = RLINK(root);
258 LLINK(p) = root;
259 RLINK(root) = Node::NullPtr;
260 }
261 return root = p; // inserted node become root
262 }
263
264public:
271 Node * insert(Node *p) noexcept
272 {
273 assert(p != Node::NullPtr);
274 assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
275
276 /* test insertion in empty tree */
277 if (root == Node::NullPtr)
278 return root = p;
279
280 const Key & key = KEY(p);
281
282 const signed char cmp_result = splay_impl(key);
283
284 if (cmp_result == CmpEqual)
285 return nullptr; // item is already in tree
286
287 return __insert(p);
288 }
289
290 Node * insert_dup(Node *p) noexcept
291 {
292 assert(p != Node::NullPtr);
293 assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
294
295 /* test insertion in empty tree */
296 if (root == Node::NullPtr)
297 return root = p;
298
299 splay_impl(KEY(p));
300
301 return __insert(p);
302 }
303
311 Node * search(const Key & key) noexcept
312 {
313 if (root == Node::NullPtr)
314 return nullptr;
315
316 const signed char cmp_result = splay_impl(key);
317
318 return cmp_result == CmpEqual ? root : nullptr;
319 }
320
322 {
323 if (root == Node::NullPtr)
324 return root = p;
325
326 const Key & key = KEY(p);
327 const signed char cmp_result = splay_impl(key);
328 if (cmp_result == CmpEqual)
329 return root;
330
331 return __insert(p);
332 }
333
343 Node * remove(const Key & key) noexcept
344 {
345 if (root == Node::NullPtr)
346 return nullptr;
347
348 const signed char cmp_result = splay_impl(key);
349 if (cmp_result != CmpEqual)
350 return nullptr; /* key not found */
351
352 Node *ret_val = root; /* store node to delete */
353
354 if (LLINK(root) == Node::NullPtr)
355 root = RLINK(root);
356 else
357 {
358 Node *p = RLINK(root);
359 root = LLINK(root);
360 splay_impl(key);
361 RLINK(root) = p;
362 }
363
364 ret_val->reset();
365
366 return ret_val;
367 }
368
371 {
372 return root;
373 }
374
375 [[nodiscard]] bool verify() const { return check_bst(root, cmp); }
376
390};
391
392
393template <typename Key, class Compare = Aleph::less<Key>>
395struct Splay_Tree : public GenTdSplayTree<BinNode, Key, Compare>
396{
398 using Base::Base;
399};
400
401
402template <typename Key, class Compare = Aleph::less<Key>>
404struct Splay_Tree_Vtl : public GenTdSplayTree<BinNodeVtl, Key, Compare>
405{
407 using Base::Base;
408};
409
410
411#endif /* TPL_SPLAY_TREE_H */
C++20 concepts for constraining comparison functors.
@ KEY
Definition btreepic.C:169
Inorder iterator on the nodes of a binary tree.
Top-down splay tree - Self-adjusting BST with amortized O(log n) operations.
bool verify() const
static constexpr signed char CmpEqual
Key key_type
The key type stored in the node.
Compare & get_compare() noexcept
NodeType< Key > Node
static constexpr signed char CmpLess
Node *& getRoot() noexcept
Get the top-down splay tree's root.
Compare & key_comp() noexcept
Returns a reference to the comparison criteria.
virtual ~GenTdSplayTree()=default
Destructor.
Node * insert_dup(Node *p) noexcept
GenTdSplayTree(Compare __cmp=Compare()) noexcept
Constructor.
static constexpr signed char CmpGreater
Node * remove(const Key &key) noexcept
Remove a key from a top down splay tree.
Node * insert(Node *p) noexcept
Inserts a node in a top-down splay tree.
Node * search(const Key &key) noexcept
Searches a key in a top-down splay tree.
Node * search_or_insert(Node *p) noexcept
signed char splay_impl(const Key &key) noexcept
void swap(GenTdSplayTree &tree) noexcept
Node * __insert(Node *p) noexcept
void splay(const Key &key) noexcept
search key within tree and splay that node, if not found it return Node::NullPtr
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 check_bst(Node *p, const Compare &cmp=Compare())
Return true if p is a binary search tree.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
and
Check uniqueness with explicit hash + equality functors.
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.
Iterator over the nodes.
Iterator() noexcept=default
Default constructor creates an "end" iterator.
#define RLINK(i, n)
#define LLINK(i, n)
gsl_rng * r
Utility functions for binary tree operations.
Basic binary tree node definitions.
DynList< int > l