CppCommon  1.0.4.1
C++ Common Library
bintree_splay.inl
Go to the documentation of this file.
1 
9 namespace CppCommon {
10 
11 template <typename T, typename TCompare>
12 template <class InputIterator>
13 inline 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 
20 template <typename T, typename TCompare>
22 {
23  return (T*)InternalLowest();
24 }
25 
26 template <typename T, typename TCompare>
27 inline const T* BinTreeSplay<T, TCompare>::lowest() const noexcept
28 {
29  return InternalLowest();
30 }
31 
32 template <typename T, typename TCompare>
33 inline 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 
42 template <typename T, typename TCompare>
44 {
45  return (T*)InternalHighest();
46 }
47 
48 template <typename T, typename TCompare>
49 inline const T* BinTreeSplay<T, TCompare>::highest() const noexcept
50 {
51  return InternalHighest();
52 }
53 
54 template <typename T, typename TCompare>
55 inline 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 
64 template <typename T, typename TCompare>
66 {
67  return iterator(this, lowest());
68 }
69 
70 template <typename T, typename TCompare>
72 {
73  return const_iterator(this, lowest());
74 }
75 
76 template <typename T, typename TCompare>
78 {
79  return const_iterator(this, lowest());
80 }
81 
82 template <typename T, typename TCompare>
84 {
85  return iterator(this, nullptr);
86 }
87 
88 template <typename T, typename TCompare>
90 {
91  return const_iterator(this, nullptr);
92 }
93 
94 template <typename T, typename TCompare>
96 {
97  return const_iterator(this, nullptr);
98 }
99 
100 template <typename T, typename TCompare>
102 {
103  return reverse_iterator(this, highest());
104 }
105 
106 template <typename T, typename TCompare>
108 {
109  return const_reverse_iterator(this, highest());
110 }
111 
112 template <typename T, typename TCompare>
114 {
115  return const_reverse_iterator(this, highest());
116 }
117 
118 template <typename T, typename TCompare>
120 {
121  return reverse_iterator(this, nullptr);
122 }
123 
124 template <typename T, typename TCompare>
126 {
127  return const_reverse_iterator(this, nullptr);
128 }
129 
130 template <typename T, typename TCompare>
132 {
133  return const_reverse_iterator(this, nullptr);
134 }
135 
136 template <typename T, typename TCompare>
138 {
139  return iterator(this, (T*)InternalFind(item));
140 }
141 
142 template <typename T, typename TCompare>
144 {
145  return const_iterator(this, InternalFind(item));
146 }
147 
148 template <typename T, typename TCompare>
149 inline 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 
189 template <typename T, typename TCompare>
191 {
192  return iterator(this, (T*)InternalLowerBound(item));
193 }
194 
195 template <typename T, typename TCompare>
197 {
198  return const_iterator(this, InternalLowerBound(item));
199 }
200 
201 template <typename T, typename TCompare>
202 inline 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 
241 template <typename T, typename TCompare>
243 {
244  return iterator(this, (T*)InternalUpperBound(item));
245 }
246 
247 template <typename T, typename TCompare>
249 {
250  return const_iterator(this, InternalUpperBound(item));
251 }
252 
253 template <typename T, typename TCompare>
254 inline 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 
282 template <typename T, typename TCompare>
283 inline std::pair<typename BinTreeSplay<T, TCompare>::iterator, bool> BinTreeSplay<T, TCompare>::insert(T& item) noexcept
284 {
285  return insert(find(item), item);
286 }
287 
288 template <typename T, typename TCompare>
289 inline 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 
329 template <typename T, typename TCompare>
330 inline T* BinTreeSplay<T, TCompare>::erase(const T& item) noexcept
331 {
332  return erase(find(item)).operator->();
333 }
334 
335 template <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 
373 template <typename T, typename TCompare>
374 inline 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 
392 template <typename T, typename TCompare>
393 inline 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 
428 template <typename T, typename TCompare>
429 inline 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 
497 template <typename T, typename TCompare>
498 inline 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 
566 template <typename T, typename TCompare>
567 inline void BinTreeSplay<T, TCompare>::clear() noexcept
568 {
569  _size = 0;
570  _root = nullptr;
571 }
572 
573 template <typename T, typename TCompare>
574 inline 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 
582 template <typename T, typename TCompare>
583 inline 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.
const_reverse_iterator crend() const noexcept
T * erase(const T &item) noexcept
Erase the given item from the binary tree.
void swap(BinTreeSplay &bintree) noexcept
Swap two instances.
C++ Common project definitions.
Definition: token_bucket.h:15
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition: filecache.inl:23
void swap(BinTreeSplay< T, TCompare > &bintree1, BinTreeSplay< T, TCompare > &bintree2) noexcept