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