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:
70 Node() : BaseNode(sizeof(Data)), data_{} {}
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
99 Data data_;
100 };
101
107 explicit RBTree(int (*compare_fun)(const Key &, const Key &))
108 : compare_fun_(compare_fun)
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 {
130 result = ToDerivedType<Data, LimitMode>(found);
131 }
132 }
133 mutex_.Unlock();
134 return result;
135 }
136
141 void Delete(BaseNode &node)
142 {
143 mutex_.Lock();
144
145 BaseNode *child = nullptr, *parent = nullptr;
147
148 if (node.left && node.right)
149 {
150 BaseNode *replace = node.right;
151 while (replace->left)
152 {
153 replace = replace->left;
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 {
187 replace->right = node.right;
188 node.right->parent = replace;
189 }
190 }
191
192 replace->parent = node.parent;
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>
237 void Insert(BaseNode &node, KeyType &&key)
238 {
239 mutex_.Lock();
240 node.left = nullptr;
241 node.right = nullptr;
242 node.parent = nullptr;
243 node.color = RbtColor::RED;
244 node.key = std::forward<KeyType>(key);
245 RbtreeInsert(node);
246 mutex_.Unlock();
247 }
248
253 uint32_t GetNum()
254 {
255 mutex_.Lock();
256 uint32_t count = 0;
257 RbtreeGetNum(root_, &count);
258 mutex_.Unlock();
259 return count;
260 }
261
272 template <typename Data, typename Func, SizeLimitMode LimitMode = SizeLimitMode::MORE>
273 ErrorCode Foreach(Func func)
274 {
275 mutex_.Lock();
276 ErrorCode result = RbtreeForeachStart<Data>(root_, func);
277 mutex_.Unlock();
278 return result;
279 }
280
288 template <typename Data>
290 {
291 mutex_.Lock();
292 Node<Data> *result = nullptr;
293 if (!node)
294 {
295 result = static_cast<Node<Data> *>(root_);
296 while (result && result->left)
297 {
298 result = static_cast<Node<Data> *>(result->left);
299 }
300 }
301 else if (node->right)
302 {
303 result = static_cast<Node<Data> *>(node->right);
304 while (result && result->left)
305 {
306 result = static_cast<Node<Data> *>(result->left);
307 }
308 }
309 else if (node->parent)
310 {
311 if (node == node->parent->left)
312 {
313 result = static_cast<Node<Data> *>(node->parent);
314 }
315 else
316 {
317 while (node->parent && node == node->parent->right)
318 {
319 node = static_cast<Node<Data> *>(node->parent);
320 }
321 result = static_cast<Node<Data> *>(node->parent);
322 }
323 }
324 mutex_.Unlock();
325 return result;
326 }
327
328 private:
329 BaseNode *root_ = nullptr;
331 int (*compare_fun_)(const Key &,
332 const Key &);
333
334 void RbtreeInsert(BaseNode &node)
335 {
336 BaseNode *parent = nullptr;
337 BaseNode **current = &root_;
338 while (*current)
339 {
340 parent = *current;
341 current =
342 (compare_fun_(node.key, parent->key) < 0) ? &parent->left : &parent->right;
343 }
344 node.parent = parent;
345 *current = &node;
346 RbtreeInsertFixup(&node);
347 }
348
349 void RbtreeInsertFixup(BaseNode *node)
350 {
351 BaseNode *parent = nullptr, *gparent = nullptr;
352
353 while ((parent = node->parent) && parent->color == RbtColor::RED)
354 {
355 gparent = parent->parent;
356
357 if (parent == gparent->left)
358 {
359 BaseNode *uncle = gparent->right;
360 if (uncle && uncle->color == RbtColor::RED)
361 {
362 uncle->color = RbtColor::BLACK;
363 parent->color = RbtColor::BLACK;
364 gparent->color = RbtColor::RED;
365 node = gparent;
366 continue;
367 }
368
369 if (node == parent->right)
370 {
371 BaseNode *tmp = nullptr;
372 RbtreeLeftRotate(parent);
373 tmp = parent;
374 parent = node;
375 node = tmp;
376 }
377
378 parent->color = RbtColor::BLACK;
379 gparent->color = RbtColor::RED;
380 RbtreeRightRotate(gparent);
381 }
382 else
383 {
384 BaseNode *uncle = gparent->left;
385 if (uncle && uncle->color == RbtColor::RED)
386 {
387 uncle->color = RbtColor::BLACK;
388 parent->color = RbtColor::BLACK;
389 gparent->color = RbtColor::RED;
390 node = gparent;
391 continue;
392 }
393
394 if (node == parent->left)
395 {
396 BaseNode *tmp = nullptr;
397 RbtreeRightRotate(parent);
398 tmp = parent;
399 parent = node;
400 node = tmp;
401 }
402
403 parent->color = RbtColor::BLACK;
404 gparent->color = RbtColor::RED;
405 RbtreeLeftRotate(gparent);
406 }
407 }
409 }
410
411 void RbtreeLeftRotate(BaseNode *x)
412 {
413 if (!x || !x->right)
414 {
415 return;
416 }
417
418 BaseNode *y = x->right;
419 x->right = y->left;
420 if (y->left)
421 {
422 y->left->parent = x;
423 }
424
425 y->parent = x->parent;
426
427 if (!x->parent)
428 {
429 root_ = y;
430 }
431 else
432 {
433 if (x == x->parent->left)
434 {
435 x->parent->left = y;
436 }
437 else
438 {
439 x->parent->right = y;
440 }
441 }
442
443 y->left = x;
444 x->parent = y;
445 }
446
447 void RbtreeRightRotate(BaseNode *y)
448 {
449 if (!y || !y->left)
450 {
451 return;
452 }
453
454 BaseNode *x = y->left;
455 y->left = x->right;
456 if (x->right)
457 {
458 x->right->parent = y;
459 }
460
461 x->parent = y->parent;
462
463 if (!y->parent)
464 {
465 root_ = x;
466 }
467 else
468 {
469 if (y == y->parent->right)
470 {
471 y->parent->right = x;
472 }
473 else
474 {
475 y->parent->left = x;
476 }
477 }
478
479 x->right = y;
480 y->parent = x;
481 }
482
483 void RbtreeDeleteFixup(BaseNode *node, BaseNode *parent)
484 {
485 BaseNode *other = nullptr;
486
487 while ((!node || node->color == RbtColor::BLACK) && node != root_)
488 {
489 if (parent->left == node)
490 {
491 other = parent->right;
492 if (other->color == RbtColor::RED)
493 {
494 other->color = RbtColor::BLACK;
495 parent->color = RbtColor::RED;
496 RbtreeLeftRotate(parent);
497 other = parent->right;
498 }
499 if ((!other->left || other->left->color == RbtColor::BLACK) &&
500 (!other->right || other->right->color == RbtColor::BLACK))
501 {
502 other->color = RbtColor::RED;
503 node = parent;
504 parent = node->parent;
505 }
506 else
507 {
508 if (!other->right || other->right->color == RbtColor::BLACK)
509 {
510 other->left->color = RbtColor::BLACK;
511 other->color = RbtColor::RED;
512 RbtreeRightRotate(other);
513 other = parent->right;
514 }
515 other->color = parent->color;
516 parent->color = RbtColor::BLACK;
517 other->right->color = RbtColor::BLACK;
518 RbtreeLeftRotate(parent);
519 node = root_;
520 break;
521 }
522 }
523 else
524 {
525 other = parent->left;
526 if (other->color == RbtColor::RED)
527 {
528 other->color = RbtColor::BLACK;
529 parent->color = RbtColor::RED;
530 RbtreeRightRotate(parent);
531 other = parent->left;
532 }
533 if ((!other->left || other->left->color == RbtColor::BLACK) &&
534 (!other->right || other->right->color == RbtColor::BLACK))
535 {
536 other->color = RbtColor::RED;
537 node = parent;
538 parent = node->parent;
539 }
540 else
541 {
542 if (!other->left || other->left->color == RbtColor::BLACK)
543 {
544 other->right->color = RbtColor::BLACK;
545 other->color = RbtColor::RED;
546 RbtreeLeftRotate(other);
547 other = parent->left;
548 }
549 other->color = parent->color;
550 parent->color = RbtColor::BLACK;
551 other->left->color = RbtColor::BLACK;
552 RbtreeRightRotate(parent);
553 node = root_;
554 break;
555 }
556 }
557 }
558 if (node)
559 {
560 node->color = RbtColor::BLACK;
561 }
562 }
563
564 template <typename Data, typename Func>
565 ErrorCode RbtreeForeachStart(BaseNode *node, Func func)
566 {
567 if (!node)
568 {
569 return ErrorCode::OK;
570 }
571
572 if (ErrorCode code =
573 RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data> *>(node->left), func);
574 code != ErrorCode::OK)
575 {
576 return code;
577 }
578
579 if (ErrorCode code = func(*reinterpret_cast<Node<Data> *>(node));
580 code != ErrorCode::OK)
581 {
582 return code;
583 }
584
585 return RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data> *>(node->right), func);
586 }
587
588 template <typename Data, typename Func>
589 ErrorCode RbtreeForeach(BaseNode *node, Func func)
590 {
591 if (!node)
592 {
593 return ErrorCode::OK;
594 }
595
596 if (ErrorCode code =
597 RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data> *>(node->left), func);
598 code != ErrorCode::OK)
599 {
600 return code;
601 }
602
603 if (ErrorCode code = func(*reinterpret_cast<Node<Data> *>(node));
604 code != ErrorCode::OK)
605 {
606 return code;
607 }
608
609 return RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data> *>(node->right), func);
610 }
611
612 void RbtreeGetNum(BaseNode *node, uint32_t *count)
613 {
614 if (!node)
615 {
616 return;
617 }
618 ++(*count);
619 RbtreeGetNum(node->left, count);
620 RbtreeGetNum(node->right, count);
621 }
622
623 BaseNode *Search(BaseNode *x, const Key &key)
624 {
625 while (x)
626 {
627 int cmp = compare_fun_(key, x->key);
628 if (cmp == 0)
629 {
630 break;
631 }
632 x = cmp < 0 ? x->left : x->right;
633 }
634 return x;
635 }
636
637 template <typename Data, SizeLimitMode LimitMode>
638 static Node<Data> *ToDerivedType(BaseNode *node)
639 {
640 if (node)
641 {
642 Assert::SizeLimitCheck<LimitMode>(sizeof(Data), node->size);
643 }
644 return static_cast<Node<Data> *>(node);
645 }
646};
647} // namespace LibXR
static void SizeLimitCheck(size_t limit, size_t size)
在非调试模式下的占位大小检查函数(无实际作用)。 Dummy size limit check for non-debug builds.
互斥锁类,提供线程同步机制 (Mutex class providing thread synchronization mechanisms).
Definition mutex.hpp:18
ErrorCode Lock()
加锁,如果锁已被占用,则阻塞等待 (Lock the mutex, blocking if it is already locked).
Definition mutex.cpp:14
void Unlock()
解锁互斥锁 (Unlock the mutex).
Definition mutex.cpp:28
红黑树的基本节点结构 (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:330
int(* compare_fun_)(const Key &, const Key &)
键值比较函数 (Function for key comparison).
Definition rbt.hpp:331
Node< Data > * ForeachDisc(Node< Data > *node)
获取红黑树的下一个中序遍历节点 (Get the next node in in-order traversal).
Definition rbt.hpp:289
BaseNode * root_
红黑树的根节点 (Root node of the Red-Black Tree).
Definition rbt.hpp:329
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:273
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:253
RbtColor
定义红黑树节点的颜色 (Enumeration for node colors in Red-Black Tree).
Definition rbt.hpp:30
@ BLACK
黑色节点 (Black node).
@ RED
红色节点 (Red node).
LibXR 命名空间
Definition ch32_gpio.hpp:9