PatchworkOS  2ca1c69
A non-POSIX operating system.
Loading...
Searching...
No Matches
rbtree.c
Go to the documentation of this file.
2
3#include <assert.h>
4
5static inline void rbtree_update(rbtree_t* tree, rbnode_t* node)
6{
7 if (tree == NULL || node == NULL || tree->update == NULL)
8 {
9 return;
10 }
11
12 tree->update(node);
13}
14
15/// @todo This could be optimized to avoid updating nodes multiple times for overlapping paths.
16static inline void rbtree_update_to_root(rbtree_t* tree, rbnode_t* node)
17{
18 if (tree == NULL || node == NULL || tree->update == NULL)
19 {
20 return;
21 }
22
23 while (node != NULL)
24 {
25 rbtree_update(tree, node);
26 node = node->parent;
27 }
28}
29
31{
32 assert(tree != NULL);
33 assert(compare != NULL);
34
35 tree->root = NULL;
36 tree->size = 0;
37 tree->compare = compare;
38 tree->update = update;
39}
40
42{
43 assert(tree != NULL);
44 assert(node != NULL);
45 assert(direction == RBNODE_LEFT || direction == RBNODE_RIGHT);
46
47 rbnode_direction_t opposite = RBNODE_OPPOSITE(direction);
48
49 rbnode_t* parent = node->parent;
50 rbnode_t* newRoot = node->children[opposite];
51 assert(newRoot != NULL);
52 rbnode_t* newChild = newRoot->children[direction];
53
54 node->children[opposite] = newChild;
55 if (newChild != NULL)
56 {
57 newChild->parent = node;
58 }
59
60 newRoot->children[direction] = node;
61
62 newRoot->parent = parent;
63 node->parent = newRoot;
64 if (parent != NULL)
65 {
66 if (node == parent->children[RBNODE_RIGHT])
67 {
68 parent->children[RBNODE_RIGHT] = newRoot;
69 }
70 else
71 {
72 parent->children[RBNODE_LEFT] = newRoot;
73 }
74 }
75 else
76 {
77 tree->root = newRoot;
78 }
79
80 rbtree_update_to_root(tree, node);
81 rbtree_update_to_root(tree, newRoot);
82
83 return newRoot;
84}
85
86static void rbtree_insert_at(rbtree_t* tree, rbnode_t* parent, rbnode_t* node, rbnode_direction_t direction)
87{
88 assert(node != NULL);
89 assert(direction == RBNODE_LEFT || direction == RBNODE_RIGHT);
90
91 node->color = RBNODE_RED;
92 node->parent = parent;
93
94 if (parent == NULL)
95 {
96 tree->root = node;
97 return;
98 }
99
100 assert(parent->children[direction] == NULL);
101 parent->children[direction] = node;
102
103 rbtree_update_to_root(tree, node);
104
105 while (true)
106 {
107 if (parent->color == RBNODE_BLACK)
108 {
109 break;
110 }
111
112 rbnode_t* grandparent = parent->parent;
113 if (grandparent == NULL)
114 {
115 parent->color = RBNODE_BLACK;
116 return;
117 }
118
119 assert(grandparent->children[RBNODE_LEFT] == parent || grandparent->children[RBNODE_RIGHT] == parent);
120 rbnode_direction_t fromParent = RBNODE_FROM_PARENT(parent);
121 rbnode_t* uncle = grandparent->children[RBNODE_OPPOSITE(fromParent)];
122 if (uncle == NULL || uncle->color == RBNODE_BLACK)
123 {
124 if (node == parent->children[RBNODE_OPPOSITE(fromParent)])
125 {
126 rbtree_rotate(tree, parent, fromParent);
127 parent = grandparent->children[fromParent];
128 }
129
130 rbtree_rotate(tree, grandparent, RBNODE_OPPOSITE(fromParent));
131 parent->color = RBNODE_BLACK;
132 grandparent->color = RBNODE_RED;
133 break;
134 }
135
136 parent->color = RBNODE_BLACK;
137 uncle->color = RBNODE_BLACK;
138 grandparent->color = RBNODE_RED;
139 node = grandparent;
140
141 parent = node->parent;
142 if (parent == NULL)
143 {
144 break;
145 }
146 assert(parent->children[RBNODE_LEFT] == node || parent->children[RBNODE_RIGHT] == node);
147 }
148}
149
151{
152 assert(tree != NULL);
153 assert(node != NULL);
154 assert(node->parent == NULL);
155 assert(node->children[RBNODE_LEFT] == NULL);
156 assert(node->children[RBNODE_RIGHT] == NULL);
157
158 rbnode_t* current = tree->root;
159 rbnode_t* parent = NULL;
160
162 while (current != NULL)
163 {
164 parent = current;
165 if (tree->compare(node, current) < 0)
166 {
167 direction = RBNODE_LEFT;
168 current = current->children[RBNODE_LEFT];
169 }
170 else
171 {
172 direction = RBNODE_RIGHT;
173 current = current->children[RBNODE_RIGHT];
174 }
175 }
176
177 rbtree_insert_at(tree, parent, node, direction);
178 tree->size++;
179
180 if (tree->root != NULL)
181 {
182 tree->root->color = RBNODE_BLACK;
183 }
184}
185
187{
188 if (node == NULL)
189 {
190 return NULL;
191 }
192
193 rbnode_t* current = node;
194 while (current->children[RBNODE_LEFT] != NULL)
195 {
196 current = current->children[RBNODE_LEFT];
197 }
198 return current;
199}
200
202{
203 if (node == NULL)
204 {
205 return NULL;
206 }
207
208 rbnode_t* current = node;
209 while (current->children[RBNODE_RIGHT] != NULL)
210 {
211 current = current->children[RBNODE_RIGHT];
212 }
213 return current;
214}
215
217{
218 assert(tree != NULL);
219 assert(a != NULL);
220 assert(b != NULL);
221
222 if (a == b)
223 {
224 return;
225 }
226
227 assert(a->parent == NULL || a->parent->children[RBNODE_LEFT] == a || a->parent->children[RBNODE_RIGHT] == a);
228 assert(b->parent == NULL || b->parent->children[RBNODE_LEFT] == b || b->parent->children[RBNODE_RIGHT] == b);
229
230 rbnode_color_t tempColor = a->color;
231 a->color = b->color;
232 b->color = tempColor;
233
234 if (a->parent == b)
235 {
236 rbnode_t* temp = a;
237 a = b;
238 b = temp;
239 }
240
241 if (b->parent == a)
242 {
243 rbnode_t* aParent = a->parent;
244
246
247 rbnode_t* otherChild = a->children[RBNODE_OPPOSITE(sideB)];
248 rbnode_t* bLeft = b->children[RBNODE_LEFT];
249 rbnode_t* bRight = b->children[RBNODE_RIGHT];
250
251 b->parent = aParent;
252 if (aParent != NULL)
253 {
254 if (aParent->children[RBNODE_LEFT] == a)
255 {
256 aParent->children[RBNODE_LEFT] = b;
257 }
258 else
259 {
260 aParent->children[RBNODE_RIGHT] = b;
261 }
262 }
263 else
264 {
265 tree->root = b;
266 }
267
268 b->children[sideB] = a;
269 a->parent = b;
270
271 b->children[RBNODE_OPPOSITE(sideB)] = otherChild;
272 if (otherChild != NULL)
273 {
274 otherChild->parent = b;
275 }
276
277 a->children[RBNODE_LEFT] = bLeft;
278 if (bLeft != NULL)
279 {
280 bLeft->parent = a;
281 }
282
283 a->children[RBNODE_RIGHT] = bRight;
284 if (bRight != NULL)
285 {
286 bRight->parent = a;
287 }
288 }
289 else
290 {
291 rbnode_t* aParent = a->parent;
292 rbnode_t* bParent = b->parent;
293 rbnode_t* aLeft = a->children[RBNODE_LEFT];
294 rbnode_t* aRight = a->children[RBNODE_RIGHT];
295 rbnode_t* bLeft = b->children[RBNODE_LEFT];
296 rbnode_t* bRight = b->children[RBNODE_RIGHT];
297
298 a->parent = bParent;
299 if (bParent != NULL)
300 {
301 if (bParent->children[RBNODE_LEFT] == b)
302 {
303 bParent->children[RBNODE_LEFT] = a;
304 }
305 else
306 {
307 bParent->children[RBNODE_RIGHT] = a;
308 }
309 }
310 else
311 {
312 tree->root = a;
313 }
314 a->children[RBNODE_LEFT] = bLeft;
315 if (bLeft != NULL)
316 {
317 bLeft->parent = a;
318 }
319 a->children[RBNODE_RIGHT] = bRight;
320 if (bRight != NULL)
321 {
322 bRight->parent = a;
323 }
324
325 b->parent = aParent;
326 if (aParent != NULL)
327 {
328 if (aParent->children[RBNODE_LEFT] == a)
329 {
330 aParent->children[RBNODE_LEFT] = b;
331 }
332 else
333 {
334 aParent->children[RBNODE_RIGHT] = b;
335 }
336 }
337 else
338 {
339 tree->root = b;
340 }
341 b->children[RBNODE_LEFT] = aLeft;
342 if (aLeft != NULL)
343 {
344 aLeft->parent = b;
345 }
346 b->children[RBNODE_RIGHT] = aRight;
347 if (aRight != NULL)
348 {
349 aRight->parent = b;
350 }
351 }
352
353 rbtree_update_to_root(tree, a);
354 rbtree_update_to_root(tree, b);
355}
356
357static void rbtree_remove_sanitize(rbtree_t* tree, rbnode_t* node)
358{
359 assert(node->parent == NULL ||
360 (node->parent->children[RBNODE_LEFT] != node && node->parent->children[RBNODE_RIGHT] != node));
361 assert(node->children[RBNODE_LEFT] == NULL || (node->children[RBNODE_LEFT]->parent != node));
362 assert(node->children[RBNODE_RIGHT] == NULL || (node->children[RBNODE_RIGHT]->parent != node));
363
364 rbtree_update_to_root(tree, node->parent);
365
366 node->parent = NULL;
367 node->children[RBNODE_LEFT] = NULL;
368 node->children[RBNODE_RIGHT] = NULL;
369 node->color = RBNODE_RED;
370
371 tree->size--;
372}
373
375{
376 assert(tree != NULL);
377 assert(node != NULL);
378
379 if (tree->size == 0 || (node != tree->root && node->parent == NULL))
380 {
381 return;
382 }
383
384 assert(node == tree->root || node->parent->children[RBNODE_LEFT] == node ||
385 node->parent->children[RBNODE_RIGHT] == node);
386
387 if (node->children[RBNODE_LEFT] != NULL && node->children[RBNODE_RIGHT] != NULL)
388 {
389 rbnode_t* successor = rbtree_find_min(node->children[RBNODE_RIGHT]);
390 assert(successor != NULL);
391 assert(successor->children[RBNODE_LEFT] == NULL);
392 rbtree_swap(tree, node, successor);
393 rbtree_remove(tree, node);
394 return;
395 }
396
397 rbnode_t* child = node->children[RBNODE_LEFT] != NULL ? node->children[RBNODE_LEFT] : node->children[RBNODE_RIGHT];
398 assert(!(node->children[RBNODE_LEFT] != NULL && node->children[RBNODE_RIGHT] != NULL));
399
400 if (node->color == RBNODE_RED)
401 {
402 assert(child == NULL);
403
404 if (node->parent == NULL)
405 {
406 tree->root = NULL;
407 }
408 else
409 {
410 rbnode_direction_t fromParent = RBNODE_FROM_PARENT(node);
411 assert(node->parent->children[fromParent] == node);
412 node->parent->children[fromParent] = NULL;
413 }
414
415 rbtree_remove_sanitize(tree, node);
416 return;
417 }
418
419 if (child != NULL)
420 {
421 assert(child->color == RBNODE_RED);
422 assert(child->parent == node);
423
424 if (node->parent == NULL)
425 {
426 tree->root = child;
427 }
428 else
429 {
430 node->parent->children[RBNODE_FROM_PARENT(node)] = child;
431 }
432
433 child->parent = node->parent;
434 child->color = RBNODE_BLACK;
435
436 rbtree_remove_sanitize(tree, node);
437 return;
438 }
439
440 rbnode_t* parent = node->parent;
441
442 if (parent == NULL)
443 {
444 tree->root = NULL;
445 rbtree_remove_sanitize(tree, node);
446 return;
447 }
448
449 rbnode_direction_t fromParent = RBNODE_FROM_PARENT(node);
450 assert(parent->children[fromParent] == node);
451 parent->children[fromParent] = NULL;
452
453 rbtree_remove_sanitize(tree, node);
454
455 // Do this very complex fixup stuff
456 rbnode_t* curr = NULL;
457 while (true)
458 {
459 rbnode_t* sibling = parent->children[RBNODE_OPPOSITE(fromParent)];
460 assert(sibling != NULL);
461
462 if (sibling->color == RBNODE_RED)
463 {
464 assert(parent->color == RBNODE_BLACK);
465 rbtree_rotate(tree, parent, fromParent);
466 parent->color = RBNODE_RED;
467 sibling->color = RBNODE_BLACK;
468 sibling = parent->children[RBNODE_OPPOSITE(fromParent)];
469 assert(sibling != NULL);
470 assert(sibling->color == RBNODE_BLACK);
471 }
472
473 rbnode_t* distantNephew = sibling->children[RBNODE_OPPOSITE(fromParent)];
474 rbnode_t* closeNephew = sibling->children[fromParent];
475
476 if ((distantNephew == NULL || distantNephew->color == RBNODE_BLACK) &&
477 (closeNephew == NULL || closeNephew->color == RBNODE_BLACK))
478 {
479 sibling->color = RBNODE_RED;
480 curr = parent;
481 parent = curr->parent;
482
483 if (parent == NULL)
484 {
485 break;
486 }
487
488 assert(parent->children[RBNODE_LEFT] == curr || parent->children[RBNODE_RIGHT] == curr);
489
490 if (curr->color == RBNODE_RED)
491 {
492 curr->color = RBNODE_BLACK;
493 break;
494 }
495
496 fromParent = RBNODE_FROM_PARENT(curr);
497 continue;
498 }
499
500 if (distantNephew == NULL || distantNephew->color == RBNODE_BLACK)
501 {
502 assert(closeNephew != NULL);
503 assert(closeNephew->color == RBNODE_RED);
504 rbtree_rotate(tree, sibling, RBNODE_OPPOSITE(fromParent));
505 sibling->color = RBNODE_RED;
506 closeNephew->color = RBNODE_BLACK;
507
508 distantNephew = sibling; // For clarity
509 sibling = closeNephew;
510 }
511
512 assert(sibling->children[RBNODE_OPPOSITE(fromParent)] != NULL);
513 assert(sibling->children[RBNODE_OPPOSITE(fromParent)]->color == RBNODE_RED);
514 rbtree_rotate(tree, parent, fromParent);
515 sibling->color = parent->color;
516 parent->color = RBNODE_BLACK;
517 if (sibling->children[RBNODE_OPPOSITE(fromParent)] != NULL)
518 {
519 sibling->children[RBNODE_OPPOSITE(fromParent)]->color = RBNODE_BLACK;
520 }
521 break;
522 }
523
524 if (tree->root != NULL)
525 {
526 tree->root->color = RBNODE_BLACK;
527 }
528}
529
530void rbtree_fix(rbtree_t* tree, rbnode_t* node)
531{
532 assert(tree != NULL);
533 assert(node != NULL);
534
535 rbtree_remove(tree, node);
536 rbtree_insert(tree, node);
537}
538
539bool rbtree_is_empty(const rbtree_t* tree)
540{
541 assert(tree != NULL);
542 assert((tree->size == 0) == (tree->root == NULL));
543 return tree->size == 0;
544}
545
547{
548 if (node == NULL)
549 {
550 return NULL;
551 }
552
553 if (node->children[RBNODE_RIGHT] != NULL)
554 {
556 }
557
558 rbnode_t* parent = node->parent;
559 while (parent != NULL && node == parent->children[RBNODE_RIGHT])
560 {
561 node = parent;
562 parent = parent->parent;
563 }
564
565 return parent;
566}
567
569{
570 if (node == NULL)
571 {
572 return NULL;
573 }
574
575 if (node->children[RBNODE_LEFT] != NULL)
576 {
577 return rbtree_find_max(node->children[RBNODE_LEFT]);
578 }
579
580 rbnode_t* parent = node->parent;
581 while (parent != NULL && node == parent->children[RBNODE_LEFT])
582 {
583 node = parent;
584 parent = parent->parent;
585 }
586
587 return parent;
588}
#define assert(expression)
Definition assert.h:29
void(* rbnode_update_t)(rbnode_t *node)
Update function for Red-Black Tree nodes.
Definition rbtree.h:131
rbnode_t * rbtree_next(const rbnode_t *node)
Get the next node in the tree, in predecessor order.
Definition rbtree.c:546
#define RBNODE_OPPOSITE(direction)
Get the opposite direction (left <-> right).
Definition rbtree.h:74
int64_t(* rbnode_compare_t)(const rbnode_t *a, const rbnode_t *b)
Comparison function for Red-Black Tree nodes.
Definition rbtree.h:122
void rbtree_swap(rbtree_t *tree, rbnode_t *a, rbnode_t *b)
Swap two nodes in the Red-Black Tree.
Definition rbtree.c:216
rbnode_t * rbtree_find_min(rbnode_t *node)
Find the minimum node in a subtree.
Definition rbtree.c:186
rbnode_color_t
Red-Black Tree Node Colors.
Definition rbtree.h:50
rbnode_direction_t
Red-Black Tree Node Directions.
Definition rbtree.h:62
rbnode_t * rbtree_rotate(rbtree_t *tree, rbnode_t *node, rbnode_direction_t direction)
Rotate a node in the Red-Black Tree.
Definition rbtree.c:41
void rbtree_init(rbtree_t *tree, rbnode_compare_t compare, rbnode_update_t update)
Initialize a Red-Black Tree.
Definition rbtree.c:30
rbnode_t * rbtree_prev(const rbnode_t *node)
Get the previous node in the tree, in predecessor order.
Definition rbtree.c:568
void rbtree_remove(rbtree_t *tree, rbnode_t *node)
Remove a node from the Red-Black Tree.
Definition rbtree.c:374
void rbtree_insert(rbtree_t *tree, rbnode_t *node)
Insert a node into the Red-Black Tree.
Definition rbtree.c:150
rbnode_t * rbtree_find_max(rbnode_t *node)
Find the maximum node in a subtree.
Definition rbtree.c:201
void rbtree_fix(rbtree_t *tree, rbnode_t *node)
Move the node to its correct position in the Red-Black Tree.
Definition rbtree.c:530
#define RBNODE_FROM_PARENT(node)
Get the direction of a node from its parent.
Definition rbtree.h:82
bool rbtree_is_empty(const rbtree_t *tree)
Check if the Red-Black Tree is empty.
Definition rbtree.c:539
@ RBNODE_BLACK
Definition rbtree.h:52
@ RBNODE_RED
Definition rbtree.h:51
@ RBNODE_RIGHT
Definition rbtree.h:64
@ RBNODE_LEFT
Definition rbtree.h:63
#define NULL
Pointer error value.
Definition NULL.h:23
static void rbtree_remove_sanitize(rbtree_t *tree, rbnode_t *node)
Definition rbtree.c:357
static void rbtree_update(rbtree_t *tree, rbnode_t *node)
Definition rbtree.c:5
static void rbtree_update_to_root(rbtree_t *tree, rbnode_t *node)
Definition rbtree.c:16
static void rbtree_insert_at(rbtree_t *tree, rbnode_t *parent, rbnode_t *node, rbnode_direction_t direction)
Definition rbtree.c:86
Red-Black Tree Node.
Definition rbtree.h:93
rbnode_t * parent
Definition rbtree.h:94
rbnode_t * children[RBNODE_AMOUNT]
Definition rbtree.h:95
rbnode_color_t color
Definition rbtree.h:96
Red-Black Tree.
Definition rbtree.h:138
rbnode_update_t update
Definition rbtree.h:142
rbnode_compare_t compare
Definition rbtree.h:141
uint64_t size
Definition rbtree.h:140
rbnode_t * root
Definition rbtree.h:139