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&)) : compare_fun_(compare_fun)
108 {
109 ASSERT(compare_fun_);
110 }
111
120 template <typename Data, SizeLimitMode LimitMode = SizeLimitMode::MORE>
121 Node<Data>* Search(const Key& key)
122 {
123 mutex_.Lock();
124 Node<Data>* result = nullptr;
125 if (root_)
126 {
127 if (BaseNode* found = Search(root_, key))
128 {
129 result = ToDerivedType<Data, LimitMode>(found);
130 }
131 }
132 mutex_.Unlock();
133 return result;
134 }
135
140 void Delete(BaseNode& node)
141 {
142 mutex_.Lock();
143
144 BaseNode *child = nullptr, *parent = nullptr;
146
147 if (node.left && node.right)
148 {
149 BaseNode* replace = node.right;
150 while (replace->left)
151 {
152 replace = replace->left;
153 }
154
155 if (node.parent)
156 {
157 (node.parent->left == &node ? node.parent->left : node.parent->right) = replace;
158 }
159 else
160 {
161 root_ = replace;
162 }
163
164 child = replace->right;
165 parent = replace->parent;
166 color = replace->color;
167
168 if (parent == &node)
169 {
170 parent = replace;
171 }
172 else
173 {
174 if (child)
175 {
176 child->parent = parent;
177 }
178
179 if (parent)
180 {
181 parent->left = child;
182 }
183
184 if (node.right)
185 {
186 replace->right = node.right;
187 node.right->parent = replace;
188 }
189 }
190
191 replace->parent = node.parent;
192 replace->color = node.color;
193 replace->left = node.left;
194 node.left->parent = replace;
195
196 if (color == RbtColor::BLACK)
197 {
198 RbtreeDeleteFixup(child, parent);
199 }
200 mutex_.Unlock();
201 return;
202 }
203
204 child = node.left ? node.left : node.right;
205 parent = node.parent;
206 color = node.color;
207
208 if (child)
209 {
210 child->parent = parent;
211 }
212
213 if (parent)
214 {
215 (parent->left == &node ? parent->left : parent->right) = child;
216 }
217 else
218 {
219 root_ = child;
220 }
221
222 if (color == RbtColor::BLACK)
223 {
224 RbtreeDeleteFixup(child, parent);
225 }
226 mutex_.Unlock();
227 }
228
235 template <typename KeyType>
236 void Insert(BaseNode& node, KeyType&& key)
237 {
238 mutex_.Lock();
239 node.left = nullptr;
240 node.right = nullptr;
241 node.parent = nullptr;
242 node.color = RbtColor::RED;
243 node.key = std::forward<KeyType>(key);
244 RbtreeInsert(node);
245 mutex_.Unlock();
246 }
247
252 uint32_t GetNum()
253 {
254 mutex_.Lock();
255 uint32_t count = 0;
256 RbtreeGetNum(root_, &count);
257 mutex_.Unlock();
258 return count;
259 }
260
271 template <typename Data, typename Func, SizeLimitMode LimitMode = SizeLimitMode::MORE>
272 ErrorCode Foreach(Func func)
273 {
274 mutex_.Lock();
275 ErrorCode result = RbtreeForeachStart<Data>(root_, func);
276 mutex_.Unlock();
277 return result;
278 }
279
287 template <typename Data>
289 {
290 mutex_.Lock();
291 Node<Data>* result = nullptr;
292 if (!node)
293 {
294 result = static_cast<Node<Data>*>(root_);
295 while (result && result->left)
296 {
297 result = static_cast<Node<Data>*>(result->left);
298 }
299 }
300 else if (node->right)
301 {
302 result = static_cast<Node<Data>*>(node->right);
303 while (result && result->left)
304 {
305 result = static_cast<Node<Data>*>(result->left);
306 }
307 }
308 else if (node->parent)
309 {
310 if (node == node->parent->left)
311 {
312 result = static_cast<Node<Data>*>(node->parent);
313 }
314 else
315 {
316 while (node->parent && node == node->parent->right)
317 {
318 node = static_cast<Node<Data>*>(node->parent);
319 }
320 result = static_cast<Node<Data>*>(node->parent);
321 }
322 }
323 mutex_.Unlock();
324 return result;
325 }
326
327 private:
328 BaseNode* root_ = nullptr;
330 int (*compare_fun_)(const Key&,
331 const Key&);
332
333 void RbtreeInsert(BaseNode& node)
334 {
335 BaseNode* parent = nullptr;
336 BaseNode** current = &root_;
337 while (*current)
338 {
339 parent = *current;
340 current =
341 (compare_fun_(node.key, parent->key) < 0) ? &parent->left : &parent->right;
342 }
343 node.parent = parent;
344 *current = &node;
345 RbtreeInsertFixup(&node);
346 }
347
348 void RbtreeInsertFixup(BaseNode* node)
349 {
350 BaseNode *parent = nullptr, *gparent = nullptr;
351
352 while ((parent = node->parent) && parent->color == RbtColor::RED)
353 {
354 gparent = parent->parent;
355
356 if (parent == gparent->left)
357 {
358 BaseNode* uncle = gparent->right;
359 if (uncle && uncle->color == RbtColor::RED)
360 {
361 uncle->color = RbtColor::BLACK;
362 parent->color = RbtColor::BLACK;
363 gparent->color = RbtColor::RED;
364 node = gparent;
365 continue;
366 }
367
368 if (node == parent->right)
369 {
370 BaseNode* tmp = nullptr;
371 RbtreeLeftRotate(parent);
372 tmp = parent;
373 parent = node;
374 node = tmp;
375 }
376
377 parent->color = RbtColor::BLACK;
378 gparent->color = RbtColor::RED;
379 RbtreeRightRotate(gparent);
380 }
381 else
382 {
383 BaseNode* uncle = gparent->left;
384 if (uncle && uncle->color == RbtColor::RED)
385 {
386 uncle->color = RbtColor::BLACK;
387 parent->color = RbtColor::BLACK;
388 gparent->color = RbtColor::RED;
389 node = gparent;
390 continue;
391 }
392
393 if (node == parent->left)
394 {
395 BaseNode* tmp = nullptr;
396 RbtreeRightRotate(parent);
397 tmp = parent;
398 parent = node;
399 node = tmp;
400 }
401
402 parent->color = RbtColor::BLACK;
403 gparent->color = RbtColor::RED;
404 RbtreeLeftRotate(gparent);
405 }
406 }
408 }
409
410 void RbtreeLeftRotate(BaseNode* x)
411 {
412 if (!x || !x->right)
413 {
414 return;
415 }
416
417 BaseNode* y = x->right;
418 x->right = y->left;
419 if (y->left)
420 {
421 y->left->parent = x;
422 }
423
424 y->parent = x->parent;
425
426 if (!x->parent)
427 {
428 root_ = y;
429 }
430 else
431 {
432 if (x == x->parent->left)
433 {
434 x->parent->left = y;
435 }
436 else
437 {
438 x->parent->right = y;
439 }
440 }
441
442 y->left = x;
443 x->parent = y;
444 }
445
446 void RbtreeRightRotate(BaseNode* y)
447 {
448 if (!y || !y->left)
449 {
450 return;
451 }
452
453 BaseNode* x = y->left;
454 y->left = x->right;
455 if (x->right)
456 {
457 x->right->parent = y;
458 }
459
460 x->parent = y->parent;
461
462 if (!y->parent)
463 {
464 root_ = x;
465 }
466 else
467 {
468 if (y == y->parent->right)
469 {
470 y->parent->right = x;
471 }
472 else
473 {
474 y->parent->left = x;
475 }
476 }
477
478 x->right = y;
479 y->parent = x;
480 }
481
482 void RbtreeDeleteFixup(BaseNode* node, BaseNode* parent)
483 {
484 BaseNode* other = nullptr;
485
486 while ((!node || node->color == RbtColor::BLACK) && node != root_)
487 {
488 if (parent->left == node)
489 {
490 other = parent->right;
491 if (other->color == RbtColor::RED)
492 {
493 other->color = RbtColor::BLACK;
494 parent->color = RbtColor::RED;
495 RbtreeLeftRotate(parent);
496 other = parent->right;
497 }
498 if ((!other->left || other->left->color == RbtColor::BLACK) &&
499 (!other->right || other->right->color == RbtColor::BLACK))
500 {
501 other->color = RbtColor::RED;
502 node = parent;
503 parent = node->parent;
504 }
505 else
506 {
507 if (!other->right || other->right->color == RbtColor::BLACK)
508 {
509 other->left->color = RbtColor::BLACK;
510 other->color = RbtColor::RED;
511 RbtreeRightRotate(other);
512 other = parent->right;
513 }
514 other->color = parent->color;
515 parent->color = RbtColor::BLACK;
516 other->right->color = RbtColor::BLACK;
517 RbtreeLeftRotate(parent);
518 node = root_;
519 break;
520 }
521 }
522 else
523 {
524 other = parent->left;
525 if (other->color == RbtColor::RED)
526 {
527 other->color = RbtColor::BLACK;
528 parent->color = RbtColor::RED;
529 RbtreeRightRotate(parent);
530 other = parent->left;
531 }
532 if ((!other->left || other->left->color == RbtColor::BLACK) &&
533 (!other->right || other->right->color == RbtColor::BLACK))
534 {
535 other->color = RbtColor::RED;
536 node = parent;
537 parent = node->parent;
538 }
539 else
540 {
541 if (!other->left || other->left->color == RbtColor::BLACK)
542 {
543 other->right->color = RbtColor::BLACK;
544 other->color = RbtColor::RED;
545 RbtreeLeftRotate(other);
546 other = parent->left;
547 }
548 other->color = parent->color;
549 parent->color = RbtColor::BLACK;
550 other->left->color = RbtColor::BLACK;
551 RbtreeRightRotate(parent);
552 node = root_;
553 break;
554 }
555 }
556 }
557 if (node)
558 {
559 node->color = RbtColor::BLACK;
560 }
561 }
562
563 template <typename Data, typename Func>
564 ErrorCode RbtreeForeachStart(BaseNode* node, Func func)
565 {
566 if (!node)
567 {
568 return ErrorCode::OK;
569 }
570
571 if (ErrorCode code =
572 RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data>*>(node->left), func);
573 code != ErrorCode::OK)
574 {
575 return code;
576 }
577
578 if (ErrorCode code = func(*reinterpret_cast<Node<Data>*>(node));
579 code != ErrorCode::OK)
580 {
581 return code;
582 }
583
584 return RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data>*>(node->right), func);
585 }
586
587 template <typename Data, typename Func>
588 ErrorCode RbtreeForeach(BaseNode* node, Func func)
589 {
590 if (!node)
591 {
592 return ErrorCode::OK;
593 }
594
595 if (ErrorCode code =
596 RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data>*>(node->left), func);
597 code != ErrorCode::OK)
598 {
599 return code;
600 }
601
602 if (ErrorCode code = func(*reinterpret_cast<Node<Data>*>(node));
603 code != ErrorCode::OK)
604 {
605 return code;
606 }
607
608 return RbtreeForeach<Data, Func>(reinterpret_cast<Node<Data>*>(node->right), func);
609 }
610
611 void RbtreeGetNum(BaseNode* node, uint32_t* count)
612 {
613 if (!node)
614 {
615 return;
616 }
617 ++(*count);
618 RbtreeGetNum(node->left, count);
619 RbtreeGetNum(node->right, count);
620 }
621
622 BaseNode* Search(BaseNode* x, const Key& key)
623 {
624 while (x)
625 {
626 int cmp = compare_fun_(key, x->key);
627 if (cmp == 0)
628 {
629 break;
630 }
631 x = cmp < 0 ? x->left : x->right;
632 }
633 return x;
634 }
635
636 template <typename Data, SizeLimitMode LimitMode>
637 static Node<Data>* ToDerivedType(BaseNode* node)
638 {
639 if (node)
640 {
641 Assert::SizeLimitCheck<LimitMode>(sizeof(Data), node->size);
642 }
643 return static_cast<Node<Data>*>(node);
644 }
645};
646} // 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:32
红黑树的基本节点结构 (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:329
int(* compare_fun_)(const Key &, const Key &)
键值比较函数 (Function for key comparison).
Definition rbt.hpp:330
Node< Data > * ForeachDisc(Node< Data > *node)
获取红黑树的下一个中序遍历节点 (Get the next node in in-order traversal).
Definition rbt.hpp:288
BaseNode * root_
红黑树的根节点 (Root node of the Red-Black Tree).
Definition rbt.hpp:328
void Delete(BaseNode &node)
从树中删除指定节点 (Delete a specified node from the tree).
Definition rbt.hpp:140
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:272
Node< Data > * Search(const Key &key)
搜索红黑树中的节点 (Search for a node in the Red-Black Tree).
Definition rbt.hpp:121
void Insert(BaseNode &node, KeyType &&key)
在树中插入新节点 (Insert a new node into the tree).
Definition rbt.hpp:236
uint32_t GetNum()
获取树中的节点数量 (Get the number of nodes in the tree).
Definition rbt.hpp:252
RbtColor
定义红黑树节点的颜色 (Enumeration for node colors in Red-Black Tree).
Definition rbt.hpp:30
@ BLACK
黑色节点 (Black node).
@ RED
红色节点 (Red node).
LibXR 命名空间
Definition ch32_can.hpp:14