CppCommon 1.0.5.0
C++ Common Library
Loading...
Searching...
No Matches
bintree_rb.inl
Go to the documentation of this file.
1
9namespace CppCommon {
10
11template <typename T, typename TCompare>
12template <class InputIterator>
13inline BinTreeRB<T, TCompare>::BinTreeRB(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* BinTreeRB<T, TCompare>::lowest() const noexcept
28{
29 return InternalLowest();
30}
31
32template <typename T, typename TCompare>
33inline const T* BinTreeRB<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* BinTreeRB<T, TCompare>::highest() const noexcept
50{
51 return InternalHighest();
52}
53
54template <typename T, typename TCompare>
55inline const T* BinTreeRB<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>
143inline typename BinTreeRB<T, TCompare>::const_iterator BinTreeRB<T, TCompare>::find(const T& item) const noexcept
144{
145 return const_iterator(this, InternalFind(item));
146}
147
148template <typename T, typename TCompare>
149inline const T* BinTreeRB<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
154 while (current != nullptr)
155 {
156 // Move to the left subtree
157 if (compare(item, *current))
158 {
159 current = current->left;
160 continue;
161 }
162
163 // Move to the right subtree
164 if (compare(*current, item))
165 {
166 current = current->right;
167 continue;
168 }
169
170 // Found result node
171 return current;
172 }
173
174 // Nothing was found...
175 return nullptr;
176}
177
178template <typename T, typename TCompare>
180{
181 return iterator(this, (T*)InternalLowerBound(item));
182}
183
184template <typename T, typename TCompare>
186{
187 return const_iterator(this, InternalLowerBound(item));
188}
189
190template <typename T, typename TCompare>
191inline const T* BinTreeRB<T, TCompare>::InternalLowerBound(const T& item) const noexcept
192{
193 // Perform the binary tree search from the root node
194 const T* current = _root;
195 const T* previous = nullptr;
196
197 while (current != nullptr)
198 {
199 // Move to the left subtree
200 if (compare(item, *current))
201 {
202 previous = current;
203 current = current->left;
204 continue;
205 }
206
207 // Move to the right subtree
208 if (compare(*current, item))
209 {
210 current = current->right;
211 continue;
212 }
213
214 // Found result node
215 return current;
216 }
217
218 // Return the previous lower bound node if any met
219 return previous;
220}
221
222template <typename T, typename TCompare>
224{
225 return iterator(this, (T*)InternalUpperBound(item));
226}
227
228template <typename T, typename TCompare>
230{
231 return const_iterator(this, InternalUpperBound(item));
232}
233
234template <typename T, typename TCompare>
235inline const T* BinTreeRB<T, TCompare>::InternalUpperBound(const T& item) const noexcept
236{
237 // Perform the binary tree search from the root node
238 const T* current = _root;
239 const T* previous = nullptr;
240
241 while (current != nullptr)
242 {
243 // Move to the left subtree
244 if (compare(item, *current))
245 {
246 previous = current;
247 current = current->left;
248 continue;
249 }
250
251 // Move to the right subtree
252 current = current->right;
253 }
254
255 // Return the previous upper bound node if any met
256 return previous;
257}
258
259template <typename T, typename TCompare>
260inline std::pair<typename BinTreeRB<T, TCompare>::iterator, bool> BinTreeRB<T, TCompare>::insert(T& item) noexcept
261{
262 return insert(const_iterator(this, _root), item);
263}
264
265template <typename T, typename TCompare>
266inline std::pair<typename BinTreeRB<T, TCompare>::iterator, bool> BinTreeRB<T, TCompare>::insert(const const_iterator& position, T& item) noexcept
267{
268 // Perform the binary tree insert from the given node
269 T* current = (T*)position.operator->();
270
271 while (current != nullptr)
272 {
273 // Move to the left subtree
274 if (compare(item, *current))
275 {
276 if (current->left != nullptr)
277 {
278 current = current->left;
279 continue;
280 }
281 else
282 {
283 // Link a new item to the left leaf
284 current->left = &item;
285 break;
286 }
287 }
288
289 // Move to the right subtree
290 if (compare(*current, item))
291 {
292 if (current->right != nullptr)
293 {
294 current = current->right;
295 continue;
296 }
297 else
298 {
299 // Link a new item to the right leaf
300 current->right = &item;
301 break;
302 }
303 }
304
305 // Found duplicate node
306 return std::make_pair(iterator(this, current), false);
307 }
308
309 item.parent = current;
310 item.left = nullptr;
311 item.right = nullptr;
312 if (_root == nullptr)
313 _root = &item;
314 ++_size;
315
316 // Balance the binary tree
317 T* node = &item;
318 // Set red color for new red-black balanced binary tree node
319 node->rb = true;
320 // Check red-black properties
321 while ((node->parent != nullptr) && node->parent->rb)
322 {
323 // We have a violation...
324 if (node->parent == node->parent->parent->left)
325 {
326 T* uncle = node->parent->parent->right;
327 if ((uncle != nullptr) && uncle->rb)
328 {
329 // Uncle is red
330 node->parent->rb = false;
331 uncle->rb = false;
332 node->parent->parent->rb = true;
333 node = node->parent->parent;
334 }
335 else
336 {
337 // Uncle is back
338 if (node == node->parent->right)
339 {
340 // Make node a left child
341 node = node->parent;
342 RotateLeft(node);
343 }
344
345 // Recolor and rotate
346 node->parent->rb = false;
347 node->parent->parent->rb = true;
348 RotateRight(node->parent->parent);
349 }
350 }
351 else
352 {
353 // Mirror image of above code...
354 T* uncle = node->parent->parent->left;
355 if ((uncle != nullptr) && uncle->rb)
356 {
357 // Uncle is red
358 node->parent->rb = false;
359 uncle->rb = false;
360 node->parent->parent->rb = true;
361 node = node->parent->parent;
362 }
363 else
364 {
365 // Uncle is black
366 if (node == node->parent->left)
367 {
368 node = node->parent;
369 RotateRight(node);
370 }
371
372 // Recolor and rotate
373 node->parent->rb = false;
374 node->parent->parent->rb = true;
375 RotateLeft(node->parent->parent);
376 }
377 }
378 }
379 _root->rb = false;
380
381 return std::make_pair(iterator(this, &item), true);
382}
383
384template <typename T, typename TCompare>
385inline T* BinTreeRB<T, TCompare>::erase(const T& item) noexcept
386{
387 return erase(find(item)).operator->();
388}
389
390template <typename T, typename TCompare>
392{
393 T* result = ((iterator&)it).operator->();
394 if (result == nullptr)
395 return end();
396
397 T* x;
398 T* y;
399 T* node = result;
400
401 if ((node->left == nullptr) || (node->right == nullptr))
402 {
403 // y has a nullptr node as a child
404 y = node;
405 }
406 else
407 {
408 // Find tree successor with a nullptr node as a child
409 y = node->right;
410 while (y->left != nullptr)
411 y = y->left;
412 }
413
414 // Swap two nodes
415 if (y != node)
416 {
417 if (node->parent == nullptr)
418 _root = y;
419 Swap(node, y);
420 }
421
422 // x is y's only child
423 if (y->left != nullptr)
424 x = y->left;
425 else
426 x = y->right;
427
428 // Remove y from the parent chain
429 if (x != nullptr)
430 x->parent = y->parent;
431 if (y->parent != nullptr)
432 {
433 if (y == y->parent->left)
434 y->parent->left = x;
435 else
436 y->parent->right = x;
437 }
438 else
439 _root = x;
440
441 // Unlink given node
442 if (!y->rb)
443 Unlink(x, y->parent);
444
445 result->parent = nullptr;
446 result->left = nullptr;
447 result->right = nullptr;
448 --_size;
449 return iterator(this, result);
450}
451
452template <typename T, typename TCompare>
453inline void BinTreeRB<T, TCompare>::RotateLeft(T* node)
454{
455 T* current = node->right;
456
457 // Establish node->right link
458 node->right = current->left;
459 if (current->left != nullptr)
460 current->left->parent = node;
461
462 // Establish current->parent link
463 current->parent = node->parent;
464 if (node->parent != nullptr)
465 {
466 if (node == node->parent->left)
467 node->parent->left = current;
468 else
469 node->parent->right = current;
470 }
471 else
472 _root = current;
473
474 // Link node and current
475 current->left = node;
476 node->parent = current;
477}
478
479template <typename T, typename TCompare>
480inline void BinTreeRB<T, TCompare>::RotateRight(T* node)
481{
482 T* current = node->left;
483
484 // Establish node->right link
485 node->left = current->right;
486 if (current->right != nullptr)
487 current->right->parent = node;
488
489 // Establish current->parent link
490 current->parent = node->parent;
491 if (node->parent != nullptr)
492 {
493 if (node == node->parent->right)
494 node->parent->right = current;
495 else
496 node->parent->left = current;
497 }
498 else
499 _root = current;
500
501 // Link node and current
502 current->right = node;
503 node->parent = current;
504}
505
506template <typename T, typename TCompare>
507inline void BinTreeRB<T, TCompare>::Unlink(T* node, T* parent)
508{
509 T* w;
510
511 while ((parent != nullptr) && ((node == nullptr) || !node->rb))
512 {
513 if (node == parent->left)
514 {
515 w = parent->right;
516 if ((w != nullptr) && w->rb)
517 {
518 w->rb = false;
519 parent->rb = true;
520 RotateLeft(parent);
521 w = parent->right;
522 }
523 if (w == nullptr)
524 break;
525 if (((w->left == nullptr) || !w->left->rb) && ((w->right == nullptr) || !w->right->rb))
526 {
527 w->rb = true;
528 node = parent;
529 parent = parent->parent;
530 }
531 else
532 {
533 if ((w->right == nullptr) || !w->right->rb)
534 {
535 w->left->rb = false;
536 w->rb = true;
537 RotateRight(w);
538 w = parent->right;
539 }
540
541 // Copy red-black color information
542 if (parent->rb)
543 w->rb = true;
544 else
545 w->rb = false;
546 parent->rb = false;
547 w->right->rb = false;
548 RotateLeft(parent);
549 node = _root;
550 parent = nullptr;
551 }
552 }
553 else
554 {
555 w = parent->left;
556 if ((w != nullptr) && w->rb)
557 {
558 w->rb = false;
559 parent->rb = true;
560 RotateRight(parent);
561 w = parent->left;
562 }
563 if (w == nullptr)
564 break;
565 if (((w->left == nullptr) || !w->left->rb) && ((w->right == nullptr) || !w->right->rb))
566 {
567 w->rb = true;
568 node = parent;
569 parent = parent->parent;
570 }
571 else
572 {
573 if ((w->left == nullptr) || !w->left->rb)
574 {
575 w->right->rb = false;
576 w->rb = true;
577 RotateLeft(w);
578 w = parent->left;
579 }
580
581 // Copy red-black color information
582 if (parent->rb)
583 w->rb = true;
584 else
585 w->rb = false;
586 parent->rb = false;
587 w->left->rb = false;
588 RotateRight(parent);
589 node = _root;
590 parent = nullptr;
591 }
592 }
593 }
594
595 if (node != nullptr)
596 node->rb = false;
597}
598
599template <typename T, typename TCompare>
600inline void BinTreeRB<T, TCompare>::Swap(T*& node1, T*& node2)
601{
602 T* first_parent = node1->parent;
603 T* first_left = node1->left;
604 T* first_right = node1->right;
605 T* second_parent = node2->parent;
606 T* second_left = node2->left;
607 T* second_right = node2->right;
608 bool first_is_left = ((first_parent != nullptr) && (first_parent->left == node1));
609 bool second_is_left = ((second_parent != nullptr) && (second_parent->left == node2));
610
611 // Update first node links
612 if (first_parent != nullptr)
613 {
614 if (first_is_left)
615 first_parent->left = node2;
616 else
617 first_parent->right = node2;
618 }
619 if (first_left != nullptr)
620 first_left->parent = node2;
621 if (first_right != nullptr)
622 first_right->parent = node2;
623
624 // Update second node links
625 if (second_parent != nullptr)
626 {
627 if (second_is_left)
628 second_parent->left = node1;
629 else
630 second_parent->right = node1;
631 }
632 if (second_left != nullptr)
633 second_left->parent = node1;
634 if (second_right != nullptr)
635 second_right->parent = node1;
636
637 // Swap node links
638 std::swap(node1->parent, node2->parent);
639 std::swap(node1->left, node2->left);
640 std::swap(node1->right, node2->right);
641 std::swap(node1->balance, node2->balance);
642
643 // Swap nodes
644 std::swap(node1, node2);
645}
646
647template <typename T, typename TCompare>
648inline void BinTreeRB<T, TCompare>::clear() noexcept
649{
650 _size = 0;
651 _root = nullptr;
652}
653
654template <typename T, typename TCompare>
655inline void BinTreeRB<T, TCompare>::swap(BinTreeRB& bintree) noexcept
656{
657 using std::swap;
658 swap(_compare, bintree._compare);
659 swap(_size, bintree._size);
660 swap(_root, bintree._root);
661}
662
663template <typename T, typename TCompare>
664inline void swap(BinTreeRB<T, TCompare>& bintree1, BinTreeRB<T, TCompare>& bintree2) noexcept
665{
666 bintree1.swap(bintree2);
667}
668
669} // 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 balanced Red-Black binary tree container.
Definition bintree_rb.h:202
T * highest() noexcept
Get the highest binary tree item.
const_iterator cend() const noexcept
const_reverse_iterator crbegin() const noexcept
BinTreeRB(const TCompare &compare=TCompare()) noexcept
Definition bintree_rb.h:229
friend void swap(BinTreeRB< U, UCompare > &bintree1, BinTreeRB< U, UCompare > &bintree2) noexcept
iterator begin() noexcept
Get the begin binary tree iterator.
reverse_iterator rbegin() noexcept
Get the reverse begin binary tree iterator.
T * erase(const T &item) noexcept
Erase the given item from the binary tree.
void clear() noexcept
Clear the binary tree.
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 ...
reverse_iterator rend() noexcept
Get the reverse end binary tree iterator.
iterator end() noexcept
Get the end binary tree iterator.
T * lowest() noexcept
Get the lowest binary tree item.
const_reverse_iterator crend() const noexcept
std::pair< iterator, bool > insert(T &item) noexcept
Insert a new item into 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_iterator cbegin() const noexcept
iterator find(const T &item) noexcept
Find the iterator which points to the first equal item in the binary tree or return end iterator.
Intrusive binary tree reverse iterator.
Definition bintree.h:392
C++ Common project definitions.
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition filecache.inl:23