1 // util/rbtree.h -- A red/black tree implementation
3 // This software is copyright (c) 2006 Scott Wood <scott@buserror.net>.
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal with
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 // of the Software, and to permit persons to whom the Software is furnished to do
10 // so, subject to the following condition:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
23 #ifndef _UTIL_RBTREE_H
24 #define _UTIL_RBTREE_H
31 // T must have an RBTree<T, NodeV, KeyV>::Node member called rbtree_node.
32 // NodeV < NodeV, NodeV < KeyV, and NodeV > KeyV must be supported.
34 // Using NodeV != KeyV allows things such as having NodeV represent a
35 // range of values and KeyV a single value, causing find() to search
36 // for the node in whose range KeyV falls. It is an error to add
37 // nodes that are not well ordered.
39 template <typename T, typename NodeV, typename KeyV>
43 Node *parent, *left, *right;
47 // A pointer to the parent's left or right pointer
48 // (whichever side this node is on). This is also
49 // used for sanity checks (it is NULL for nodes not
56 parent = left = right = NULL;
62 return parentlink != NULL;
69 T *node_to_type(Node *n)
71 return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(n) -
72 offsetof(T, rbtree_node));
75 void assert_rb_condition(Node *left, Node *right)
77 assert(left->value < right->value);
78 assert(!(right->value < left->value));
79 assert(!left->red || !right->red);
82 void assert_well_ordered(Node *left, NodeV right)
84 assert(left->value < right);
85 assert(!(left->value > right));
86 assert(!left->red || !right->red);
89 Node *find_node(Node *n, NodeV &val, Node ***link);
90 Node *find_node_key(KeyV val, bool exact = true);
92 bool node_is_left(Node *n)
94 assert(n->parentlink == &n->parent->left ||
95 n->parentlink == &n->parent->right);
97 return n->parentlink == &n->parent->left;
100 Node *sibling(Node *n)
103 return n->parent->right;
105 return n->parent->left;
110 return sibling(n->parent);
113 void rotate_left(Node *n);
114 void rotate_right(Node *n);
116 // B must have no right child and have A as an ancestor.
117 void swap(Node *a, Node *b);
137 Node *n = find_node_key(value);
140 return node_to_type(n);
145 T *find_nearest(KeyV value)
147 Node *n = find_node_key(value, false);
150 return node_to_type(n);
152 // Should only happen on an empty tree
160 template <typename T, typename NodeV, typename KeyV>
161 typename RBTree<T, NodeV, KeyV>::Node *
162 RBTree<T, NodeV, KeyV>::find_node(Node *n, NodeV &val, Node ***link)
168 *link = n->parentlink;
178 if (n->value < val) {
182 assert_rb_condition(n, next);
190 // This assert detects duplicate nodes, but not
191 // overlapping ranges (or otherwise non-well-ordered
194 assert(val < n->value);
198 assert_rb_condition(next, n);
213 template <typename T, typename NodeV, typename KeyV>
214 typename RBTree<T, NodeV, KeyV>::Node *
215 RBTree<T, NodeV, KeyV>::find_node_key(KeyV val, bool exact)
222 if (n->value < val) {
226 assert_rb_condition(n, next);
227 } else if (n->value > val) {
231 assert_rb_condition(next, n);
245 template <typename T, typename NodeV, typename KeyV>
246 void RBTree<T, NodeV, KeyV>::rotate_left(Node *n)
248 Node *new_top = n->right;
250 assert(*n->parentlink == n);
251 *n->parentlink = new_top;
253 assert(new_top->parent == n);
254 assert(new_top->parentlink == &n->right);
256 new_top->parent = n->parent;
257 new_top->parentlink = n->parentlink;
260 n->parentlink = &new_top->left;
262 n->right = new_top->left;
266 assert(n->right->parent == new_top);
267 assert(n->right->parentlink == &new_top->left);
269 n->right->parent = n;
270 n->right->parentlink = &n->right;
274 template <typename T, typename NodeV, typename KeyV>
275 void RBTree<T, NodeV, KeyV>::rotate_right(Node *n)
277 Node *new_top = n->left;
279 assert(*n->parentlink == n);
280 *n->parentlink = new_top;
282 assert(new_top->parent == n);
283 assert(new_top->parentlink == &n->left);
285 new_top->parent = n->parent;
286 new_top->parentlink = n->parentlink;
289 n->parentlink = &new_top->right;
291 n->left = new_top->right;
295 assert(n->left->parent == new_top);
296 assert(n->left->parentlink == &new_top->right);
299 n->left->parentlink = &n->left;
303 // B must have no right child and have A as an ancestor.
304 template <typename T, typename NodeV, typename KeyV>
305 void RBTree<T, NodeV, KeyV>::swap(Node *a, Node *b)
307 Node *bparent = b->parent;
308 Node **bparentlink = b->parentlink;
311 assert(a->left || a->right);
313 b->parent = a->parent;
314 b->parentlink = a->parentlink;
318 a->parentlink = &b->left;
321 a->parentlink = bparentlink;
324 assert(a->parent != a);
325 assert(b->parent != b);
327 Node *bleft = b->left;
337 assert(a->parent != a);
338 assert(b->parent != b);
346 a->left->parentlink = &a->left;
350 b->right->parent = b;
351 b->right->parentlink = &b->right;
356 b->left->parentlink = &b->left;
359 template <typename T, typename NodeV, typename KeyV>
360 void RBTree<T, NodeV, KeyV>::add(T *t)
362 Node *n = &t->rbtree_node;
363 assert(!n->is_on_rbtree());
365 Node *insert_at = find_node(top, n->value, &n->parentlink);
367 assert(insert_at || !top);
369 n->parent = insert_at;
370 n->left = n->right = NULL;
373 assert(n->parentlink);
374 assert(*n->parentlink == n);
381 assert(n->parent->value < n->value != n->value < n->parent->value);
387 Node *unc = uncle(n);
389 assert(!n->parent->parent->red);
390 n->parent->red = unc->red = false;
391 n = n->parent->parent;
395 if (node_is_left(n)) {
396 if (!node_is_left(n->parent)) {
397 rotate_right(n->parent);
401 if (node_is_left(n->parent)) {
402 rotate_left(n->parent);
407 assert(n->parent->red);
408 assert(!red(uncle(n)));
409 assert(!n->parent->parent->red);
411 n->parent->red = false;
412 n->parent->parent->red = true;
414 if (node_is_left(n)) {
415 assert(node_is_left(n->parent));
416 rotate_right(n->parent->parent);
418 assert(!node_is_left(n->parent));
419 rotate_left(n->parent->parent);
423 template <typename T, typename NodeV, typename KeyV>
424 void RBTree<T, NodeV, KeyV>::del(T *t)
426 Node *n = &t->rbtree_node;
427 assert(*n->parentlink == n);
429 if (n->left && n->right) {
430 Node *highest_on_left = find_node(n->left, n->value, NULL);
431 assert(!highest_on_left->right);
432 swap(n, highest_on_left);
436 Node *parent = n->parent;
437 Node *child = n->left ? n->left : n->right;
440 assert(child->parent == n);
442 child->parent = n->parent;
443 child->parentlink = n->parentlink;
444 *child->parentlink = child;
445 assert(child != parent);
447 *n->parentlink = NULL;
450 n->parentlink = NULL;
473 sib = parent->left ? parent->left : parent->right;
476 assert(!parent->red);
477 assert(!red(sib->left));
478 assert(!red(sib->right));
483 if (node_is_left(sib)) {
484 rotate_right(parent);
492 assert(sib == sibling(n));
493 } else if (!parent->red && !red(sib->left) && !red(sib->right)) {
497 parent = parent->parent;
503 if (!parent->red && !red(sib->left) && !red(sib->right)) {
509 if (!red(sib->left) && !red(sib->right)) {
516 if (node_is_left(sib) && !red(sib->left) && red(sib->right)) {
518 sib->right->red = false;
521 } else if (!node_is_left(sib) && !red(sib->right) && red(sib->left)) {
523 sib->left->red = false;
528 assert(parent == sib->parent);
531 sib->red = parent->red;
534 if (node_is_left(sib)) {
535 assert(sib->left->red);
536 sib->left->red = false;
537 rotate_right(parent);
539 assert(sib->right->red);
540 sib->right->red = false;