CppCommon 1.0.5.0
C++ Common Library
Loading...
Searching...
No Matches
bintree_aa.inl
Go to the documentation of this file.
1
9namespace CppCommon {
10
11template <typename T, typename TCompare>
12template <class InputIterator>
13inline BinTreeAA<T, TCompare>::BinTreeAA(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* BinTreeAA<T, TCompare>::lowest() const noexcept
28{
29 return InternalLowest();
30}
31
32template <typename T, typename TCompare>
33inline const T* BinTreeAA<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* BinTreeAA<T, TCompare>::highest() const noexcept
50{
51 return InternalHighest();
52}
53
54template <typename T, typename TCompare>
55inline const T* BinTreeAA<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 BinTreeAA<T, TCompare>::const_iterator BinTreeAA<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* BinTreeAA<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* BinTreeAA<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* BinTreeAA<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 BinTreeAA<T, TCompare>::iterator, bool> BinTreeAA<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 BinTreeAA<T, TCompare>::iterator, bool> BinTreeAA<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 node->level = 1;
319 while (node->parent != nullptr)
320 {
321 node = node->parent;
322 if (node->level != ((node->left != nullptr) ? node->left->level + 1 : 1))
323 {
324 Skew(node);
325 if ((node->right == nullptr) || (node->level != node->right->level))
326 node = node->parent;
327 }
328
329 if (!Split(node->parent))
330 break;
331 }
332
333 return std::make_pair(iterator(this, &item), true);
334}
335
336template <typename T, typename TCompare>
337inline T* BinTreeAA<T, TCompare>::erase(const T& item) noexcept
338{
339 return erase(find(item)).operator->();
340}
341
342template <typename T, typename TCompare>
344{
345 T* result = ((iterator&)it).operator->();
346 if (result == nullptr)
347 return end();
348
349 T* node = result;
350 T* temp;
351
352 if (result->left != nullptr)
353 {
354 node = result->left;
355 while (node->right != nullptr)
356 node = node->right;
357 }
358 else if (result->right != nullptr)
359 node = result->right;
360
361 temp = ((node->parent == result) ? node : node->parent);
362 if (node->parent != nullptr)
363 {
364 if (node->parent->left == node)
365 node->parent->left = nullptr;
366 else
367 node->parent->right = nullptr;
368 }
369 else
370 _root = nullptr;
371
372 if (result != node)
373 {
374 if (result->parent != nullptr)
375 {
376 if (result->parent->left == result)
377 result->parent->left = node;
378 else
379 result->parent->right = node;
380 }
381 else
382 _root = node;
383
384 node->parent = result->parent;
385 if (result->left != nullptr)
386 result->left->parent = node;
387 node->left = result->left;
388 if (result->right != nullptr)
389 result->right->parent = node;
390 node->right = result->right;
391
392 // Copy levels
393 node->level = result->level;
394 }
395
396 while (temp != nullptr)
397 {
398 if (temp->level > ((temp->left != nullptr) ? temp->left->level + 1 : 1))
399 {
400 temp->level = temp->level - 1;
401 if (Split(temp))
402 {
403 if (Split(temp))
404 Skew(temp->parent->parent);
405 break;
406 }
407 }
408 else if (temp->level <= ((temp->right != nullptr) ? temp->right->level + 1 : 1))
409 break;
410 else
411 {
412 Skew(temp);
413 if (temp->level > temp->parent->level)
414 {
415 Skew(temp);
416 Split(temp->parent->parent);
417 break;
418 }
419 temp = temp->parent;
420 }
421 temp = temp->parent;
422 }
423
424 result->parent = nullptr;
425 result->left = nullptr;
426 result->right = nullptr;
427 --_size;
428 return iterator(this, result);
429}
430
431template <typename T, typename TCompare>
432inline void BinTreeAA<T, TCompare>::Skew(T* node)
433{
434 if (node == nullptr)
435 return;
436
437 T* current = node->left;
438 if (node->parent != nullptr)
439 {
440 if (node->parent->left == node)
441 node->parent->left = current;
442 else
443 node->parent->right = current;
444 }
445 else
446 _root = current;
447 current->parent = node->parent;
448 node->parent = current;
449
450 node->left = current->right;
451 if (node->left != nullptr)
452 node->left->parent = node;
453 current->right = node;
454
455 if (node->left != nullptr)
456 node->level = node->left->level + 1;
457 else
458 node->level = 1;
459}
460
461template <typename T, typename TCompare>
462inline bool BinTreeAA<T, TCompare>::Split(T* node)
463{
464 if (node == nullptr)
465 return false;
466
467 T* current = node->right;
468 if ((current != nullptr) && (current->right != nullptr) && (current->right->level == node->level))
469 {
470 if (node->parent != nullptr)
471 {
472 if (node->parent->left == node)
473 node->parent->left = current;
474 else
475 node->parent->right = current;
476 }
477 else
478 _root = current;
479 current->parent = node->parent;
480 node->parent = current;
481
482 node->right = current->left;
483 if (node->right != nullptr)
484 node->right->parent = node;
485 current->left = node;
486 current->level = node->level + 1;
487 return true;
488 }
489
490 return false;
491}
492
493template <typename T, typename TCompare>
494inline void BinTreeAA<T, TCompare>::clear() noexcept
495{
496 _size = 0;
497 _root = nullptr;
498}
499
500template <typename T, typename TCompare>
501inline void BinTreeAA<T, TCompare>::swap(BinTreeAA& bintree) noexcept
502{
503 using std::swap;
504 swap(_compare, bintree._compare);
505 swap(_size, bintree._size);
506 swap(_root, bintree._root);
507}
508
509template <typename T, typename TCompare>
510inline void swap(BinTreeAA<T, TCompare>& bintree1, BinTreeAA<T, TCompare>& bintree2) noexcept
511{
512 bintree1.swap(bintree2);
513}
514
515} // namespace CppCommon
Intrusive balanced A.Andersson binary tree container.
Definition bintree_aa.h:60
void clear() noexcept
Clear the binary tree.
const_reverse_iterator crend() const noexcept
friend void swap(BinTreeAA< U, UCompare > &bintree1, BinTreeAA< U, UCompare > &bintree2) noexcept
iterator begin() noexcept
Get the begin 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 ...
BinTreeAA(const TCompare &compare=TCompare()) noexcept
Definition bintree_aa.h:87
reverse_iterator rend() noexcept
Get the reverse end binary tree iterator.
const_reverse_iterator crbegin() const noexcept
iterator end() noexcept
Get the end binary tree iterator.
const_iterator cbegin() const noexcept
T * lowest() noexcept
Get the lowest binary tree item.
const_iterator cend() const noexcept
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.
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...
T * erase(const T &item) noexcept
Erase the given item from the binary tree.
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.
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
C++ Common project definitions.
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition filecache.inl:23