CppCommon 1.0.5.0
C++ Common Library
Loading...
Searching...
No Matches
bintree_splay.inl
Go to the documentation of this file.
1
9namespace CppCommon {
10
11template <typename T, typename TCompare>
12template <class InputIterator>
13inline BinTreeSplay<T, TCompare>::BinTreeSplay(InputIterator first, InputIterator last, const TCompare& compare) noexcept
14 : _compare(compare)
15{
16 for (auto it = first; it != last; ++it)
17 insert(*it);
18}
19
20template <typename T, typename TCompare>
22{
23 return (T*)InternalLowest();
24}
25
26template <typename T, typename TCompare>
27inline const T* BinTreeSplay<T, TCompare>::lowest() const noexcept
28{
29 return InternalLowest();
30}
31
32template <typename T, typename TCompare>
33inline const T* BinTreeSplay<T, TCompare>::InternalLowest() const noexcept
34{
35 const T* result = _root;
36 if (result != nullptr)
37 while (result->left != nullptr)
38 result = result->left;
39 return result;
40}
41
42template <typename T, typename TCompare>
44{
45 return (T*)InternalHighest();
46}
47
48template <typename T, typename TCompare>
49inline const T* BinTreeSplay<T, TCompare>::highest() const noexcept
50{
51 return InternalHighest();
52}
53
54template <typename T, typename TCompare>
55inline const T* BinTreeSplay<T, TCompare>::InternalHighest() const noexcept
56{
57 const T* result = _root;
58 if (result != nullptr)
59 while (result->right != nullptr)
60 result = result->right;
61 return result;
62}
63
64template <typename T, typename TCompare>
66{
67 return iterator(this, lowest());
68}
69
70template <typename T, typename TCompare>
72{
73 return const_iterator(this, lowest());
74}
75
76template <typename T, typename TCompare>
78{
79 return const_iterator(this, lowest());
80}
81
82template <typename T, typename TCompare>
84{
85 return iterator(this, nullptr);
86}
87
88template <typename T, typename TCompare>
90{
91 return const_iterator(this, nullptr);
92}
93
94template <typename T, typename TCompare>
96{
97 return const_iterator(this, nullptr);
98}
99
100template <typename T, typename TCompare>
102{
103 return reverse_iterator(this, highest());
104}
105
106template <typename T, typename TCompare>
108{
109 return const_reverse_iterator(this, highest());
110}
111
112template <typename T, typename TCompare>
114{
115 return const_reverse_iterator(this, highest());
116}
117
118template <typename T, typename TCompare>
120{
121 return reverse_iterator(this, nullptr);
122}
123
124template <typename T, typename TCompare>
126{
127 return const_reverse_iterator(this, nullptr);
128}
129
130template <typename T, typename TCompare>
132{
133 return const_reverse_iterator(this, nullptr);
134}
135
136template <typename T, typename TCompare>
138{
139 return iterator(this, (T*)InternalFind(item));
140}
141
142template <typename T, typename TCompare>
144{
145 return const_iterator(this, InternalFind(item));
146}
147
148template <typename T, typename TCompare>
149inline const T* BinTreeSplay<T, TCompare>::InternalFind(const T& item) const noexcept
150{
151 // Perform the binary tree search from the root node
152 const T* current = _root;
153 const T* previous = nullptr;
154
155 while (current != nullptr)
156 {
157 // Move to the left subtree
158 if (compare(item, *current))
159 {
160 previous = current;
161 current = current->left;
162 continue;
163 }
164
165 // Move to the right subtree
166 if (compare(*current, item))
167 {
168 previous = current;
169 current = current->right;
170 continue;
171 }
172
173 // Balance the binary tree
174 if (current != nullptr)
175 Splay((T*)current);
176
177 // Found result node
178 return current;
179 }
180
181 // Balance the binary tree
182 if (previous != nullptr)
183 Splay((T*)previous);
184
185 // Nothing was found...
186 return nullptr;
187}
188
189template <typename T, typename TCompare>
191{
192 return iterator(this, (T*)InternalLowerBound(item));
193}
194
195template <typename T, typename TCompare>
197{
198 return const_iterator(this, InternalLowerBound(item));
199}
200
201template <typename T, typename TCompare>
202inline const T* BinTreeSplay<T, TCompare>::InternalLowerBound(const T& item) const noexcept
203{
204 // Perform the binary tree search from the root node
205 const T* current = _root;
206 const T* previous = nullptr;
207
208 while (current != nullptr)
209 {
210 // Move to the left subtree
211 if (compare(item, *current))
212 {
213 previous = current;
214 current = current->left;
215 continue;
216 }
217
218 // Move to the right subtree
219 if (compare(*current, item))
220 {
221 current = current->right;
222 continue;
223 }
224
225 // Balance the binary tree
226 if (current != nullptr)
227 Splay((T*)current);
228
229 // Found result node
230 return current;
231 }
232
233 // Balance the binary tree
234 if (previous != nullptr)
235 Splay((T*)previous);
236
237 // Return the previous lower bound node if any met
238 return previous;
239}
240
241template <typename T, typename TCompare>
243{
244 return iterator(this, (T*)InternalUpperBound(item));
245}
246
247template <typename T, typename TCompare>
249{
250 return const_iterator(this, InternalUpperBound(item));
251}
252
253template <typename T, typename TCompare>
254inline const T* BinTreeSplay<T, TCompare>::InternalUpperBound(const T& item) const noexcept
255{
256 // Perform the binary tree search from the root node
257 const T* current = _root;
258 const T* previous = nullptr;
259
260 while (current != nullptr)
261 {
262 // Move to the left subtree
263 if (compare(item, *current))
264 {
265 previous = current;
266 current = current->left;
267 continue;
268 }
269
270 // Move to the right subtree
271 current = current->right;
272 }
273
274 // Balance the binary tree
275 if (previous != nullptr)
276 Splay((T*)previous);
277
278 // Return the previous upper bound node if any met
279 return previous;
280}
281
282template <typename T, typename TCompare>
283inline std::pair<typename BinTreeSplay<T, TCompare>::iterator, bool> BinTreeSplay<T, TCompare>::insert(T& item) noexcept
284{
285 return insert(find(item), item);
286}
287
288template <typename T, typename TCompare>
289inline std::pair<typename BinTreeSplay<T, TCompare>::iterator, bool> BinTreeSplay<T, TCompare>::insert(const const_iterator& position, T& item) noexcept
290{
291 // Perform the binary tree insert from the given node
292 T* current = (T*)position.operator->();
293 if (current != nullptr)
294 {
295 // Found duplicate node
296 return std::make_pair(iterator(this, current), false);
297 }
298
299 item.parent = nullptr;
300 item.left = nullptr;
301 item.right = nullptr;
302 if (_root != nullptr)
303 {
304 if (compare(item, *_root))
305 {
306 item.left = _root->left;
307 item.right = _root;
308 _root->parent = &item;
309 if (_root->left != nullptr)
310 _root->left->parent = &item;
311 _root->left = nullptr;
312 }
313 else
314 {
315 item.right = _root->right;
316 item.left = _root;
317 _root->parent = &item;
318 if (_root->right != nullptr)
319 _root->right->parent = &item;
320 _root->right = nullptr;
321 }
322 }
323 _root = &item;
324 ++_size;
325
326 return std::make_pair(iterator(this, &item), true);
327}
328
329template <typename T, typename TCompare>
330inline T* BinTreeSplay<T, TCompare>::erase(const T& item) noexcept
331{
332 return erase(find(item)).operator->();
333}
334
335template <typename T, typename TCompare>
337{
338 T* result = ((iterator&)it).operator->();
339 if (result == nullptr)
340 return end();
341
342 if (result->left == nullptr)
343 {
344 _root = result->right;
345 if (_root != nullptr)
346 _root->parent = nullptr;
347 }
348 else if (result->right == nullptr)
349 {
350 _root = result->left;
351 if (_root != nullptr)
352 _root->parent = nullptr;
353 }
354 else
355 {
356 _root = result->left;
357 _root->parent = nullptr;
358 T* highest = result->left;
359 while (highest->right != nullptr)
360 highest = highest->right;
361 highest->right = result->right;
362 if (highest->right != nullptr)
363 highest->right->parent = highest;
364 }
365
366 result->parent = nullptr;
367 result->left = nullptr;
368 result->right = nullptr;
369 --_size;
370 return iterator(this, result);
371}
372
373template <typename T, typename TCompare>
374inline void BinTreeSplay<T, TCompare>::Splay(T* x) const
375{
376 while (x->parent != nullptr)
377 {
378 T* p = x->parent;
379 T* g = p->parent;
380 if (g == nullptr)
381 Zig(x);
382 else if ((g->left == p) && (p->left == x))
383 ZigZig(x);
384 else if ((g->right == p) && (p->right == x))
385 ZigZig(x);
386 else
387 ZigZag(x);
388 }
389 (T*&)_root = x;
390}
391
392template <typename T, typename TCompare>
393inline void BinTreeSplay<T, TCompare>::Zig(T* x) const
394{
395 T* p = x->parent;
396 if (p->left == x)
397 {
398 [[maybe_unused]] T* a = x->left;
399 [[maybe_unused]] T* b = x->right;
400 [[maybe_unused]] T* c = p->right;
401
402 x->parent = nullptr;
403 x->right = p;
404
405 p->parent = x;
406 p->left = b;
407
408 if (b != nullptr)
409 b->parent = p;
410 }
411 else
412 {
413 [[maybe_unused]] T* a = p->left;
414 [[maybe_unused]] T* b = x->left;
415 [[maybe_unused]] T* c = x->right;
416
417 x->parent = nullptr;
418 x->left = p;
419
420 p->parent = x;
421 p->right = b;
422
423 if (b != nullptr)
424 b->parent = p;
425 }
426}
427
428template <typename T, typename TCompare>
429inline void BinTreeSplay<T, TCompare>::ZigZig(T* x) const
430{
431 T* p = x->parent;
432 T* g = p->parent;
433 if (p->left == x)
434 {
435 [[maybe_unused]] T* a = x->left;
436 [[maybe_unused]] T* b = x->right;
437 [[maybe_unused]] T* c = p->right;
438 [[maybe_unused]] T* d = g->right;
439
440 x->parent = g->parent;
441 x->right = p;
442
443 p->parent = x;
444 p->left = b;
445 p->right = g;
446
447 g->parent = p;
448 g->left = c;
449
450 if (x->parent != nullptr)
451 {
452 if (x->parent->left == g)
453 x->parent->left = x;
454 else
455 x->parent->right = x;
456 }
457
458 if (b != nullptr)
459 b->parent = p;
460
461 if (c != nullptr)
462 c->parent = g;
463 }
464 else
465 {
466 [[maybe_unused]] T* a = g->left;
467 [[maybe_unused]] T* b = p->left;
468 [[maybe_unused]] T* c = x->left;
469 [[maybe_unused]] T* d = x->right;
470
471 x->parent = g->parent;
472 x->left = p;
473
474 p->parent = x;
475 p->left = g;
476 p->right = c;
477
478 g->parent = p;
479 g->right = b;
480
481 if (x->parent != nullptr)
482 {
483 if (x->parent->left == g)
484 x->parent->left = x;
485 else
486 x->parent->right = x;
487 }
488
489 if (b != nullptr)
490 b->parent = g;
491
492 if (c != nullptr)
493 c->parent = p;
494 }
495}
496
497template <typename T, typename TCompare>
498inline void BinTreeSplay<T, TCompare>::ZigZag(T* x) const
499{
500 T* p = x->parent;
501 T* g = p->parent;
502 if (p->right == x)
503 {
504 [[maybe_unused]] T* a = p->left;
505 [[maybe_unused]] T* b = x->left;
506 [[maybe_unused]] T* c = x->right;
507 [[maybe_unused]] T* d = g->right;
508
509 x->parent = g->parent;
510 x->left = p;
511 x->right = g;
512
513 p->parent = x;
514 p->right = b;
515
516 g->parent = x;
517 g->left = c;
518
519 if (x->parent != nullptr)
520 {
521 if (x->parent->left == g)
522 x->parent->left = x;
523 else
524 x->parent->right = x;
525 }
526
527 if (b != nullptr)
528 b->parent = p;
529
530 if (c != nullptr)
531 c->parent = g;
532 }
533 else
534 {
535 [[maybe_unused]] T* a = g->left;
536 [[maybe_unused]] T* b = x->left;
537 [[maybe_unused]] T* c = x->right;
538 [[maybe_unused]] T* d = p->right;
539
540 x->parent = g->parent;
541 x->left = g;
542 x->right = p;
543
544 p->parent = x;
545 p->left = c;
546
547 g->parent = x;
548 g->right = b;
549
550 if (x->parent != nullptr)
551 {
552 if (x->parent->left == g)
553 x->parent->left = x;
554 else
555 x->parent->right = x;
556 }
557
558 if (b != nullptr)
559 b->parent = g;
560
561 if (c != nullptr)
562 c->parent = p;
563 }
564}
565
566template <typename T, typename TCompare>
568{
569 _size = 0;
570 _root = nullptr;
571}
572
573template <typename T, typename TCompare>
574inline void BinTreeSplay<T, TCompare>::swap(BinTreeSplay& bintree) noexcept
575{
576 using std::swap;
577 swap(_compare, bintree._compare);
578 swap(_size, bintree._size);
579 swap(_root, bintree._root);
580}
581
582template <typename T, typename TCompare>
583inline void swap(BinTreeSplay<T, TCompare>& bintree1, BinTreeSplay<T, TCompare>& bintree2) noexcept
584{
585 bintree1.swap(bintree2);
586}
587
588} // namespace CppCommon
Intrusive binary tree constant iterator.
Definition bintree.h:335
Intrusive binary tree constant reverse iterator.
Definition bintree.h:448
Intrusive binary tree iterator.
Definition bintree.h:279
Intrusive binary tree reverse iterator.
Definition bintree.h:392
Intrusive balanced Splay binary tree container.
reverse_iterator rend() noexcept
Get the reverse end binary tree iterator.
BinTreeSplay(const TCompare &compare=TCompare()) noexcept
const_iterator cbegin() const noexcept
iterator end() noexcept
Get the end binary tree iterator.
iterator upper_bound(const T &item) noexcept
Find the iterator which points to the first item that greater than the given item in the binary tree ...
iterator lower_bound(const T &item) noexcept
Find the iterator which points to the first item that not less than the given item in the binary tree...
const_reverse_iterator crbegin() const noexcept
void clear() noexcept
Clear the binary tree.
T * highest() noexcept
Get the highest binary tree item.
iterator find(const T &item) noexcept
Find the iterator which points to the first equal item in the binary tree or return end iterator.
const_iterator cend() const noexcept
std::pair< iterator, bool > insert(T &item) noexcept
Insert a new item into the binary tree.
reverse_iterator rbegin() noexcept
Get the reverse begin binary tree iterator.
T * lowest() noexcept
Get the lowest binary tree item.
iterator begin() noexcept
Get the begin binary tree iterator.
friend void swap(BinTreeSplay< U, UCompare > &bintree1, BinTreeSplay< U, UCompare > &bintree2) noexcept
const_reverse_iterator crend() const noexcept
T * erase(const T &item) noexcept
Erase the given item from the binary tree.
C++ Common project definitions.
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition filecache.inl:23