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
52using namespace Aleph;
53
54
133template <template <class> class NodeType, typename Key, class Compare>
135{
136public:
138
139private:
142 Compare cmp;
143 static constexpr signed char CmpLess = -1;
144 static constexpr signed char CmpEqual = 0;
145 static constexpr signed char CmpGreater = 1;
146
147 signed char splay_impl(const Key & key) noexcept
148 {
149 Node headNode;
150 Node *l = &headNode;
151 Node *r = &headNode;
152 Node *t = root;
153 signed char cmp_result = CmpEqual;
154
155 while (true)
156 {
157 if (const Key & tk = KEY(t); cmp(key, tk)) // key < tk: go left
158 {
160 if (LLINK(t) == Node::NullPtr) [[unlikely]]
161 break;
162
163 if (cmp(key, KEY(LLINK(t)))) // zig-zig case
164 {
165 t = rotate_to_right(t);
166 if (LLINK(t) == Node::NullPtr) [[unlikely]]
167 break;
168 }
169
170 LLINK(r) = t;
171 r = t;
172 t = LLINK(t);
173 }
174 else if (cmp(tk, key)) // tk < key: go right
175 {
177 if (RLINK(t) == Node::NullPtr) [[unlikely]]
178 break;
179
180 if (cmp(KEY(RLINK(t)), key)) // zig-zig case
181 {
182 t = rotate_to_left(t);
183 if (RLINK(t) == Node::NullPtr) [[unlikely]]
184 break;
185 }
186
187 RLINK(l) = t;
188 l = t;
189 t = RLINK(t);
190 }
191 else [[unlikely]] // key == tk: found
192 {
194 break;
195 }
196 }
197
198 /* reassembling of subtrees in one with current as root */
199 RLINK(l) = LLINK(t);
200 LLINK(r) = RLINK(t);
201 LLINK(t) = headNode.getR();
202 RLINK(t) = headNode.getL();
203
204 root = t;
205
206 return cmp_result;
207 }
208
209public:
211 using key_type = Key;
212
214 Compare &key_comp() noexcept { return cmp; }
215
217 Compare &get_compare() noexcept { return key_comp(); }
218
221 void splay(const Key & key) noexcept
222 {
223 (void) splay_impl(key);
224 }
225
227 GenTdSplayTree(Compare __cmp = Compare()) noexcept
228 : head(&headnode), root(headnode.getR()), cmp(__cmp)
229 {
230 // Empty
231 }
232
233 void swap(GenTdSplayTree & tree) noexcept
234 {
235 std::swap(root, tree.root);
236 std::swap(cmp, tree.cmp);
237 }
238
240 virtual ~GenTdSplayTree() = default;
241
242private:
243 Node * __insert(Node *p) noexcept
244 {
245 const Key & pk = KEY(p);
246 const Key & rk = KEY(root);
247 if (cmp(pk, rk))
248 { /* root is predecessor of p */
249 LLINK(p) = LLINK(root);
250 RLINK(p) = root;
251 LLINK(root) = Node::NullPtr;
252 }
253 else
254 { /* root is successor of p */
255 RLINK(p) = RLINK(root);
256 LLINK(p) = root;
257 RLINK(root) = Node::NullPtr;
258 }
259 return root = p; // inserted node become root
260 }
261
262public:
269 Node * insert(Node *p) noexcept
270 {
271 assert(p != Node::NullPtr);
272 assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
273
274 /* test insertion in empty tree */
275 if (root == Node::NullPtr)
276 return root = p;
277
278 const Key & key = KEY(p);
279
280 const signed char cmp_result = splay_impl(key);
281
282 if (cmp_result == CmpEqual)
283 return nullptr; // item is already in tree
284
285 return __insert(p);
286 }
287
288 Node * insert_dup(Node *p) noexcept
289 {
290 assert(p != Node::NullPtr);
291 assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
292
293 /* test insertion in empty tree */
294 if (root == Node::NullPtr)
295 return root = p;
296
297 splay_impl(KEY(p));
298
299 return __insert(p);
300 }
301
309 Node * search(const Key & key) noexcept
310 {
311 if (root == Node::NullPtr)
312 return nullptr;
313
314 const signed char cmp_result = splay_impl(key);
315
316 return cmp_result == CmpEqual ? root : nullptr;
317 }
318
320 {
321 if (root == Node::NullPtr)
322 return root = p;
323
324 const Key & key = KEY(p);
325 const signed char cmp_result = splay_impl(key);
326 if (cmp_result == CmpEqual)
327 return root;
328
329 return __insert(p);
330 }
331
341 Node * remove(const Key & key) noexcept
342 {
343 if (root == Node::NullPtr)
344 return nullptr;
345
346 const signed char cmp_result = splay_impl(key);
347 if (cmp_result != CmpEqual)
348 return nullptr; /* key not found */
349
350 Node *ret_val = root; /* store node to delete */
351
352 if (LLINK(root) == Node::NullPtr)
353 root = RLINK(root);
354 else
355 {
356 Node *p = RLINK(root);
357 root = LLINK(root);
358 splay_impl(key);
359 RLINK(root) = p;
360 }
361
362 ret_val->reset();
363
364 return ret_val;
365 }
366
369 {
370 return root;
371 }
372
373 [[nodiscard]] bool verify() const { return check_bst(root, cmp); }
374
388};
389
390
391template <typename Key, class Compare = Aleph::less<Key>>
392struct Splay_Tree : public GenTdSplayTree<BinNode, Key, Compare>
393{
395 using Base::Base;
396};
397
398
399template <typename Key, class Compare = Aleph::less<Key>>
400struct Splay_Tree_Vtl : public GenTdSplayTree<BinNodeVtl, Key, Compare>
401{
403 using Base::Base;
404};
405
406
407#endif /* TPL_SPLAY_TREE_H */
@ KEY
Definition btreepic.C:169
Inorder iterator on the nodes of a binary tree.
void reset() noexcept
Definition htlist.H:516
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.
constexpr Node *& RLINK(Node *p) noexcept
Return the right tree of p.
constexpr Node *& LLINK(Node *p) noexcept
Return a pointer to left subtree.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
Iterator over the nodes.
Iterator() noexcept=default
Default constructor creates an "end" iterator.
Utility functions for binary tree operations.
Basic binary tree node definitions.
DynList< int > l