libxr 1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
rbt.hpp
1#pragma once
2
3#include <cstring>
4
5#include "libxr_assert.hpp"
6#include "libxr_def.hpp"
7#include "mutex.hpp"
8
9namespace LibXR
10{
22template <typename Key>
23class RBTree
24{
25 public:
29 enum class RbtColor : uint8_t
30 {
31 RED,
32 BLACK
33 };
34
39 {
40 public:
41 Key key;
43 BaseNode *left = nullptr;
44 BaseNode *right = nullptr;
45 BaseNode *parent = nullptr;
46 size_t size;
47
48 protected:
53 explicit BaseNode(size_t size) : size(size) {}
54 };
55
62 template <typename Data>
63 class Node : public BaseNode
64 {
65 public:
71
77 explicit Node(const Data &data) : BaseNode(sizeof(Data)), data_(data) {}
78
84 template <typename... Args>
85 explicit Node(Args... args) : BaseNode(sizeof(Data)), data_{args...}
86 {
87 }
88
89 operator Data &() { return data_; }
90 Node &operator=(const Data &data)
91 {
92 data_ = data;
93 return *this;
94 }
95 Data *operator->() { return &data_; }
96 const Data *operator->() const { return &data_; }
97 Data &operator*() { return data_; }
98
100 };
101
107 explicit RBTree(int (*compare_fun)(const Key &, const Key &))
109 {
110 ASSERT(compare_fun_);
111 }
112
121 template <typename Data, SizeLimitMode LimitMode = SizeLimitMode::MORE>
122 Node<Data> *Search(const Key &key)
123 {
124 mutex_.Lock();
125 Node<Data> *result = nullptr;
126 if (root_)
127 {
128 if (BaseNode *found = Search(root_, key))
129 {
131 }
132 }
133 mutex_.Unlock();
134 return result;
135 }
136
142 {
143 mutex_.Lock();
144
145 BaseNode *child = nullptr, *parent = nullptr;
147
148 if (node.left && node.right)
149 {
151 while (replace->left)
152 {
154 }
155
156 if (node.parent)
157 {
158 (node.parent->left == &node ? node.parent->left : node.parent->right) = replace;
159 }
160 else
161 {
162 root_ = replace;
163 }
164
165 child = replace->right;
166 parent = replace->parent;
167 color = replace->color;
168
169 if (parent == &node)
170 {
171 parent = replace;
172 }
173 else
174 {
175 if (child)
176 {
177 child->parent = parent;
178 }
179
180 if (parent)
181 {
182 parent->left = child;
183 }
184
185 if (node.right)
186 {
189 }
190 }
191
193 replace->color = node.color;
194 replace->left = node.left;
195 node.left->parent = replace;
196
197 if (color == RbtColor::BLACK)
198 {
199 RbtreeDeleteFixup(child, parent);
200 }
201 mutex_.Unlock();
202 return;
203 }
204
205 child = node.left ? node.left : node.right;
206 parent = node.parent;
207 color = node.color;
208
209 if (child)
210 {
211 child->parent = parent;
212 }
213
214 if (parent)
215 {
216 (parent->left == &node ? parent->left : parent->right) = child;
217 }
218 else
219 {
220 root_ = child;
221 }
222
223 if (color == RbtColor::BLACK)
224 {
225 RbtreeDeleteFixup(child, parent);
226 }
227 mutex_.Unlock();
228 }
229
236 template <typename KeyType>
238 {
239 mutex_.Lock();
240 node.left = nullptr;
241 node.right = nullptr;
242 node.parent = nullptr;
243 node.color = RbtColor::RED;
244 node.key = key;
245 node.color = RbtColor::RED;
246 node.key = std::forward<KeyType>(key);
247 RbtreeInsert(node);
248 mutex_.Unlock();
249 }
250
256 {
257 mutex_.Lock();
258 uint32_t count = 0;
259 RbtreeGetNum(root_, &count);
260 mutex_.Unlock();
261 return count;
262 }
263
274 template <typename Data, typename Func, SizeLimitMode LimitMode = SizeLimitMode::MORE>
275 ErrorCode Foreach(Func func)
276 {
277 mutex_.Lock();
279 mutex_.Unlock();
280 return result;
281 }
282
290 template <typename Data>
292 {
293 mutex_.Lock();
294 Node<Data> *result = nullptr;
295 if (!node)
296 {
297 result = static_cast<Node<Data> *>(root_);
298 while (result && result->left)
299 {
300 result = static_cast<Node<Data> *>(result->left);
301 }
302 }
303 else if (node->right)
304 {
305 result = static_cast<Node<Data> *>(node->right);
306 while (result && result->left)
307 {
308 result = static_cast<Node<Data> *>(result->left);
309 }
310 }
311 else if (node->parent)
312 {
313 if (node == node->parent->left)
314 {
315 result = static_cast<Node<Data> *>(node->parent);
316 }
317 else
318 {
319 while (node->parent && node == node->parent->right)
320 {
321 node = static_cast<Node<Data> *>(node->parent);
322 }
323 result = static_cast<Node<Data> *>(node->parent);
324 }
325 }
326 mutex_.Unlock();
327 return result;
328 }
329
330 private:
331 BaseNode *root_ = nullptr;
333 int (*compare_fun_)(const Key &,
334 const Key &);
335
336 void RbtreeInsert(BaseNode &node)
337 {
338 BaseNode *parent = nullptr;
340 while (*current)
341 {
342 parent = *current;
343 current =
344 (compare_fun_(node.key, parent->key) < 0) ? &parent->left : &parent->right;
345 }
346 node.parent = parent;
347 *current = &node;
348 RbtreeInsertFixup(&node);
349 }
350
351 void RbtreeInsertFixup(BaseNode *node)
352 {
353 BaseNode *parent = nullptr, *gparent = nullptr;
354
355 while ((parent = node->parent) && parent->color == RbtColor::RED)
356 {
357 gparent = parent->parent;
358
359 if (parent == gparent->left)
360 {
361 BaseNode *uncle = gparent->right;
362 if (uncle && uncle->color == RbtColor::RED)
363 {
364 uncle->color = RbtColor::BLACK;
365 parent->color = RbtColor::BLACK;
366 gparent->color = RbtColor::RED;
367 node = gparent;
368 continue;
369 }
370
371 if (node == parent->right)
372 {
373 BaseNode *tmp = nullptr;
374 RbtreeLeftRotate(parent);
375 tmp = parent;
376 parent = node;
377 node = tmp;
378 }
379
380 parent->color = RbtColor::BLACK;
381 gparent->color = RbtColor::RED;
382 RbtreeRightRotate(gparent);
383 }
384 else
385 {
386 BaseNode *uncle = gparent->left;
387 if (uncle && uncle->color == RbtColor::RED)
388 {
389 uncle->color = RbtColor::BLACK;
390 parent->color = RbtColor::BLACK;
391 gparent->color = RbtColor::RED;
392 node = gparent;
393 continue;
394 }
395
396 if (node == parent->left)
397 {
398 BaseNode *tmp = nullptr;
399 RbtreeRightRotate(parent);
400 tmp = parent;
401 parent = node;
402 node = tmp;
403 }
404
405 parent->color = RbtColor::BLACK;
406 gparent->color = RbtColor::RED;
407 RbtreeLeftRotate(gparent);
408 }
409 }
411 }
412
413 void RbtreeLeftRotate(BaseNode *x)
414 {
415 if (!x || !x->right)
416 {
417 return;
418 }
419
420 BaseNode *y = x->right;
421 x->right = y->left;
422 if (y->left)
423 {
424 y->left->parent = x;
425 }
426
427 y->parent = x->parent;
428
429 if (!x->parent)
430 {
431 root_ = y;
432 }
433 else
434 {
435 if (x == x->parent->left)
436 {
437 x->parent->left = y;
438 }
439 else
440 {
441 x->parent->right = y;
442 }
443 }
444
445 y->left = x;
446 x->parent = y;
447 }
448
449 void RbtreeRightRotate(BaseNode *y)
450 {
451 if (!y || !y->left)
452 {
453 return;
454 }
455
456 BaseNode *x = y->left;
457 y->left = x->right;
458 if (x->right)
459 {
460 x->right->parent = y;
461 }
462
463 x->parent = y->parent;
464
465 if (!y->parent)
466 {
467 root_ = x;
468 }
469 else
470 {
471 if (y == y->parent->right)
472 {
473 y->parent->right = x;
474 }
475 else
476 {
477 y->parent->left = x;
478 }
479 }
480
481 x->right = y;
482 y->parent = x;
483 }
484
485 void RbtreeDeleteFixup(BaseNode *node, BaseNode *parent)
486 {
487 BaseNode *other = nullptr;
488
489 while ((!node || node->color == RbtColor::BLACK) && node != root_)
490 {
491 if (parent->left == node)
492 {
493 other = parent->right;
494 if (other->color == RbtColor::RED)
495 {
497 parent->color = RbtColor::RED;
498 RbtreeLeftRotate(parent);
499 other = parent->right;
500 }
501 if ((!other->left || other->left->color == RbtColor::BLACK) &&
502 (!other->right || other->right->color == RbtColor::BLACK))
503 {
504 other->color = RbtColor::RED;
505 node = parent;
506 parent = node->parent;
507 }
508 else
509 {
510 if (!other->right || other->right->color == RbtColor::BLACK)
511 {
512 other->left->color = RbtColor::BLACK;
513 other->color = RbtColor::RED;
514 RbtreeRightRotate(other);
515 other = parent->right;
516 }
517 other->color = parent->color;
518 parent->color = RbtColor::BLACK;
519 other->right->color = RbtColor::BLACK;
520 RbtreeLeftRotate(parent);
521 node = root_;
522 break;
523 }
524 }
525 else
526 {
527 other = parent->left;
528 if (other->color == RbtColor::RED)
529 {
531 parent->color = RbtColor::RED;
532 RbtreeRightRotate(parent);
533 other = parent->left;
534 }
535 if ((!other->left || other->left->color == RbtColor::BLACK) &&
536 (!other->right || other->right->color == RbtColor::BLACK))
537 {
538 other->color = RbtColor::RED;
539 node = parent;
540 parent = node->parent;
541 }
542 else
543 {
544 if (!other->left || other->left->color == RbtColor::BLACK)
545 {
546 other->right->color = RbtColor::BLACK;
547 other->color = RbtColor::RED;
548 RbtreeLeftRotate(other);
549 other = parent->left;
550 }
551 other->color = parent->color;
552 parent->color = RbtColor::BLACK;
553 other->left->color = RbtColor::BLACK;
554 RbtreeRightRotate(parent);
555 node = root_;
556 break;
557 }
558 }
559 }
560 if (node)
561 {
563 }
564 }
565
566 template <typename Data, typename Func>
567 ErrorCode RbtreeForeachStart(BaseNode *node, Func func)
568 {
569 if (!node)
570 {
571 return ErrorCode::OK;
572 }
573
574 if (ErrorCode code =
575 RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data> *>(node->left), func);
576 code != ErrorCode::OK)
577 {
578 return code;
579 }
580
581 if (ErrorCode code = func(*reinterpret_cast<Node<Data> *>(node));
582 code != ErrorCode::OK)
583 {
584 return code;
585 }
586
587 return RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data> *>(node->right), func);
588 }
589
590 template <typename Data, typename Func>
591 ErrorCode RbtreeForeach(BaseNode *node, Func func)
592 {
593 if (!node)
594 {
595 return ErrorCode::OK;
596 }
597
598 if (ErrorCode code =
599 RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data> *>(node->left), func);
600 code != ErrorCode::OK)
601 {
602 return code;
603 }
604
605 if (ErrorCode code = func(*reinterpret_cast<Node<Data> *>(node));
606 code != ErrorCode::OK)
607 {
608 return code;
609 }
610
611 return RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data> *>(node->right), func);
612 }
613
614 void RbtreeGetNum(BaseNode *node, uint32_t *count)
615 {
616 if (!node)
617 {
618 return;
619 }
620 ++(*count);
621 RbtreeGetNum(node->left, count);
622 RbtreeGetNum(node->right, count);
623 }
624
625 BaseNode *Search(BaseNode *x, const Key &key)
626 {
627 while (x)
628 {
629 int cmp = compare_fun_(key, x->key);
630 if (cmp == 0)
631 {
632 break;
633 }
634 x = cmp < 0 ? x->left : x->right;
635 }
636 return x;
637 }
638
639 template <typename Data, SizeLimitMode LimitMode>
640 static Node<Data> *ToDerivedType(BaseNode *node)
641 {
642 if (node)
643 {
644 Assert::SizeLimitCheck<LimitMode>(sizeof(Data), node->size);
645 }
646 return static_cast<Node<Data> *>(node);
647 }
648};
649} // namespace LibXR
互斥锁类,提供线程同步机制 (Mutex class providing thread synchronization mechanisms).
Definition mutex.hpp:18
ErrorCode Lock()
加锁,如果锁已被占用,则阻塞等待 (Lock the mutex, blocking if it is already locked).
Definition mutex.cpp:13
void Unlock()
解锁互斥锁 (Unlock the mutex).
Definition mutex.cpp:27
红黑树的基本节点结构 (Base node structure of the Red-Black Tree).
Definition rbt.hpp:39
BaseNode * right
右子节点 (Right child node).
Definition rbt.hpp:44
BaseNode(size_t size)
基本节点构造函数 (Constructor for BaseNode).
Definition rbt.hpp:53
Key key
节点键值 (Key associated with the node).
Definition rbt.hpp:41
RbtColor color
节点颜色 (Color of the node).
Definition rbt.hpp:42
size_t size
节点大小 (Size of the node).
Definition rbt.hpp:46
BaseNode * left
左子节点 (Left child node).
Definition rbt.hpp:43
BaseNode * parent
父节点 (Parent node).
Definition rbt.hpp:45
红黑树的泛型数据节点,继承自 BaseNode (Generic data node for Red-Black Tree, inheriting from BaseNode).
Definition rbt.hpp:64
Node()
默认构造函数,初始化数据为空 (Default constructor initializing an empty node).
Definition rbt.hpp:70
Data data_
存储的数据 (Stored data).
Definition rbt.hpp:99
Node(const Data &data)
使用指定数据构造节点 (Constructor initializing a node with the given data).
Definition rbt.hpp:77
Node(Args... args)
通过参数列表构造节点 (Constructor initializing a node using arguments list).
Definition rbt.hpp:85
红黑树实现,支持泛型键和值,并提供线程安全操作 (Red-Black Tree implementation supporting generic keys and values with thread...
Definition rbt.hpp:24
LibXR::Mutex mutex_
互斥锁,确保线程安全 (Mutex for thread-safety).
Definition rbt.hpp:332
int(* compare_fun_)(const Key &, const Key &)
键值比较函数 (Function for key comparison).
Definition rbt.hpp:333
Node< Data > * ForeachDisc(Node< Data > *node)
获取红黑树的下一个中序遍历节点 (Get the next node in in-order traversal).
Definition rbt.hpp:291
BaseNode * root_
红黑树的根节点 (Root node of the Red-Black Tree).
Definition rbt.hpp:331
void Delete(BaseNode &node)
从树中删除指定节点 (Delete a specified node from the tree).
Definition rbt.hpp:141
RBTree(int(*compare_fun)(const Key &, const Key &))
构造函数,初始化红黑树 (Constructor initializing the Red-Black Tree).
Definition rbt.hpp:107
ErrorCode Foreach(Func func)
遍历红黑树并执行用户提供的操作 (Traverse the Red-Black Tree and apply a user-defined function).
Definition rbt.hpp:275
Node< Data > * Search(const Key &key)
搜索红黑树中的节点 (Search for a node in the Red-Black Tree).
Definition rbt.hpp:122
void Insert(BaseNode &node, KeyType &&key)
在树中插入新节点 (Insert a new node into the tree).
Definition rbt.hpp:237
uint32_t GetNum()
获取树中的节点数量 (Get the number of nodes in the tree).
Definition rbt.hpp:255
RbtColor
定义红黑树节点的颜色 (Enumeration for node colors in Red-Black Tree).
Definition rbt.hpp:30
@ BLACK
黑色节点 (Black node).
@ RED
红色节点 (Red node).
LibXR Color Control Library / LibXR终端颜色控制库
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值