1 /*
2 * Copyright © 2017 Faith Ekstrand
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23 #include "rb_tree.h"
24
25 /** \file rb_tree.c
26 *
27 * An implementation of a red-black tree
28 *
29 * This file implements the guts of a red-black tree. The implementation
30 * is mostly based on the one in "Introduction to Algorithms", third
31 * edition, by Cormen, Leiserson, Rivest, and Stein. The primary
32 * divergence in our algorithms from those presented in CLRS is that we use
33 * NULL for the leaves instead of a sentinel. This means we have to do a
34 * tiny bit more tracking in our implementation of delete but it makes the
35 * algorithms far more explicit than stashing stuff in the sentinel.
36 */
37
38 #include <stdlib.h>
39 #include <string.h>
40 #include <assert.h>
41
42 static bool
rb_node_is_black(struct rb_node * n)43 rb_node_is_black(struct rb_node *n)
44 {
45 /* NULL nodes are leaves and therefore black */
46 return (n == NULL) || (n->parent & 1);
47 }
48
49 static bool
rb_node_is_red(struct rb_node * n)50 rb_node_is_red(struct rb_node *n)
51 {
52 return !rb_node_is_black(n);
53 }
54
55 static void
rb_node_set_black(struct rb_node * n)56 rb_node_set_black(struct rb_node *n)
57 {
58 n->parent |= 1;
59 }
60
61 static void
rb_node_set_red(struct rb_node * n)62 rb_node_set_red(struct rb_node *n)
63 {
64 n->parent &= ~1ull;
65 }
66
67 static void
rb_node_copy_color(struct rb_node * dst,struct rb_node * src)68 rb_node_copy_color(struct rb_node *dst, struct rb_node *src)
69 {
70 dst->parent = (dst->parent & ~1ull) | (src->parent & 1);
71 }
72
73 static void
rb_node_set_parent(struct rb_node * n,struct rb_node * p)74 rb_node_set_parent(struct rb_node *n, struct rb_node *p)
75 {
76 n->parent = (n->parent & 1) | (uintptr_t)p;
77 }
78
79 static struct rb_node *
rb_node_minimum(struct rb_node * node)80 rb_node_minimum(struct rb_node *node)
81 {
82 while (node->left)
83 node = node->left;
84 return node;
85 }
86
87 static struct rb_node *
rb_node_maximum(struct rb_node * node)88 rb_node_maximum(struct rb_node *node)
89 {
90 while (node->right)
91 node = node->right;
92 return node;
93 }
94
95 /**
96 * Replace the subtree of T rooted at u with the subtree rooted at v
97 *
98 * This is called RB-transplant in CLRS.
99 *
100 * The node to be replaced is assumed to be a non-leaf.
101 */
102 static void
rb_tree_splice(struct rb_tree * T,struct rb_node * u,struct rb_node * v)103 rb_tree_splice(struct rb_tree *T, struct rb_node *u, struct rb_node *v)
104 {
105 assert(u);
106 struct rb_node *p = rb_node_parent(u);
107 if (p == NULL) {
108 assert(T->root == u);
109 T->root = v;
110 } else if (u == p->left) {
111 p->left = v;
112 } else {
113 assert(u == p->right);
114 p->right = v;
115 }
116 if (v)
117 rb_node_set_parent(v, p);
118 }
119
120 static void
rb_tree_rotate_left(struct rb_tree * T,struct rb_node * x)121 rb_tree_rotate_left(struct rb_tree *T, struct rb_node *x)
122 {
123 assert(x && x->right);
124
125 struct rb_node *y = x->right;
126 x->right = y->left;
127 if (y->left)
128 rb_node_set_parent(y->left, x);
129 rb_tree_splice(T, x, y);
130 y->left = x;
131 rb_node_set_parent(x, y);
132 }
133
134 static void
rb_tree_rotate_right(struct rb_tree * T,struct rb_node * y)135 rb_tree_rotate_right(struct rb_tree *T, struct rb_node *y)
136 {
137 assert(y && y->left);
138
139 struct rb_node *x = y->left;
140 y->left = x->right;
141 if (x->right)
142 rb_node_set_parent(x->right, y);
143 rb_tree_splice(T, y, x);
144 x->right = y;
145 rb_node_set_parent(y, x);
146 }
147
148 void
rb_tree_insert_at(struct rb_tree * T,struct rb_node * parent,struct rb_node * node,bool insert_left)149 rb_tree_insert_at(struct rb_tree *T, struct rb_node *parent,
150 struct rb_node *node, bool insert_left)
151 {
152 /* This sets null children, parent, and a color of red */
153 memset(node, 0, sizeof(*node));
154
155 if (parent == NULL) {
156 assert(T->root == NULL);
157 T->root = node;
158 rb_node_set_black(node);
159 return;
160 }
161
162 if (insert_left) {
163 assert(parent->left == NULL);
164 parent->left = node;
165 } else {
166 assert(parent->right == NULL);
167 parent->right = node;
168 }
169 rb_node_set_parent(node, parent);
170
171 /* Now we do the insertion fixup */
172 struct rb_node *z = node;
173 while (rb_node_is_red(rb_node_parent(z))) {
174 struct rb_node *z_p = rb_node_parent(z);
175 assert(z == z_p->left || z == z_p->right);
176 struct rb_node *z_p_p = rb_node_parent(z_p);
177 assert(z_p_p != NULL);
178 if (z_p == z_p_p->left) {
179 struct rb_node *y = z_p_p->right;
180 if (rb_node_is_red(y)) {
181 rb_node_set_black(z_p);
182 rb_node_set_black(y);
183 rb_node_set_red(z_p_p);
184 z = z_p_p;
185 } else {
186 if (z == z_p->right) {
187 z = z_p;
188 rb_tree_rotate_left(T, z);
189 /* We changed z */
190 z_p = rb_node_parent(z);
191 assert(z == z_p->left || z == z_p->right);
192 z_p_p = rb_node_parent(z_p);
193 }
194 rb_node_set_black(z_p);
195 rb_node_set_red(z_p_p);
196 rb_tree_rotate_right(T, z_p_p);
197 }
198 } else {
199 struct rb_node *y = z_p_p->left;
200 if (rb_node_is_red(y)) {
201 rb_node_set_black(z_p);
202 rb_node_set_black(y);
203 rb_node_set_red(z_p_p);
204 z = z_p_p;
205 } else {
206 if (z == z_p->left) {
207 z = z_p;
208 rb_tree_rotate_right(T, z);
209 /* We changed z */
210 z_p = rb_node_parent(z);
211 assert(z == z_p->left || z == z_p->right);
212 z_p_p = rb_node_parent(z_p);
213 }
214 rb_node_set_black(z_p);
215 rb_node_set_red(z_p_p);
216 rb_tree_rotate_left(T, z_p_p);
217 }
218 }
219 }
220 rb_node_set_black(T->root);
221 }
222
223 void
rb_tree_remove(struct rb_tree * T,struct rb_node * z)224 rb_tree_remove(struct rb_tree *T, struct rb_node *z)
225 {
226 /* x_p is always the parent node of X. We have to track this
227 * separately because x may be NULL.
228 */
229 struct rb_node *x, *x_p;
230 struct rb_node *y = z;
231 bool y_was_black = rb_node_is_black(y);
232 if (z->left == NULL) {
233 x = z->right;
234 x_p = rb_node_parent(z);
235 rb_tree_splice(T, z, x);
236 } else if (z->right == NULL) {
237 x = z->left;
238 x_p = rb_node_parent(z);
239 rb_tree_splice(T, z, x);
240 } else {
241 /* Find the minimum sub-node of z->right */
242 y = rb_node_minimum(z->right);
243 y_was_black = rb_node_is_black(y);
244
245 x = y->right;
246 if (rb_node_parent(y) == z) {
247 x_p = y;
248 } else {
249 x_p = rb_node_parent(y);
250 rb_tree_splice(T, y, x);
251 y->right = z->right;
252 rb_node_set_parent(y->right, y);
253 }
254 assert(y->left == NULL);
255 rb_tree_splice(T, z, y);
256 y->left = z->left;
257 rb_node_set_parent(y->left, y);
258 rb_node_copy_color(y, z);
259 }
260
261 assert(x_p == NULL || x == x_p->left || x == x_p->right);
262
263 if (!y_was_black)
264 return;
265
266 /* Fixup RB tree after the delete */
267 while (x != T->root && rb_node_is_black(x)) {
268 if (x == x_p->left) {
269 struct rb_node *w = x_p->right;
270 if (rb_node_is_red(w)) {
271 rb_node_set_black(w);
272 rb_node_set_red(x_p);
273 rb_tree_rotate_left(T, x_p);
274 assert(x == x_p->left);
275 w = x_p->right;
276 }
277 if (rb_node_is_black(w->left) && rb_node_is_black(w->right)) {
278 rb_node_set_red(w);
279 x = x_p;
280 } else {
281 if (rb_node_is_black(w->right)) {
282 rb_node_set_black(w->left);
283 rb_node_set_red(w);
284 rb_tree_rotate_right(T, w);
285 w = x_p->right;
286 }
287 rb_node_copy_color(w, x_p);
288 rb_node_set_black(x_p);
289 rb_node_set_black(w->right);
290 rb_tree_rotate_left(T, x_p);
291 x = T->root;
292 }
293 } else {
294 struct rb_node *w = x_p->left;
295 if (rb_node_is_red(w)) {
296 rb_node_set_black(w);
297 rb_node_set_red(x_p);
298 rb_tree_rotate_right(T, x_p);
299 assert(x == x_p->right);
300 w = x_p->left;
301 }
302 if (rb_node_is_black(w->right) && rb_node_is_black(w->left)) {
303 rb_node_set_red(w);
304 x = x_p;
305 } else {
306 if (rb_node_is_black(w->left)) {
307 rb_node_set_black(w->right);
308 rb_node_set_red(w);
309 rb_tree_rotate_left(T, w);
310 w = x_p->left;
311 }
312 rb_node_copy_color(w, x_p);
313 rb_node_set_black(x_p);
314 rb_node_set_black(w->left);
315 rb_tree_rotate_right(T, x_p);
316 x = T->root;
317 }
318 }
319 x_p = rb_node_parent(x);
320 }
321 if (x)
322 rb_node_set_black(x);
323 }
324
325 struct rb_node *
rb_tree_first(struct rb_tree * T)326 rb_tree_first(struct rb_tree *T)
327 {
328 return T->root ? rb_node_minimum(T->root) : NULL;
329 }
330
331 struct rb_node *
rb_tree_last(struct rb_tree * T)332 rb_tree_last(struct rb_tree *T)
333 {
334 return T->root ? rb_node_maximum(T->root) : NULL;
335 }
336
337 struct rb_node *
rb_node_next(struct rb_node * node)338 rb_node_next(struct rb_node *node)
339 {
340 if (node->right) {
341 /* If we have a right child, then the next thing (compared to this
342 * node) is the left-most child of our right child.
343 */
344 return rb_node_minimum(node->right);
345 } else {
346 /* If node doesn't have a right child, crawl back up the to the
347 * left until we hit a parent to the right.
348 */
349 struct rb_node *p = rb_node_parent(node);
350 while (p && node == p->right) {
351 node = p;
352 p = rb_node_parent(node);
353 }
354 assert(p == NULL || node == p->left);
355 return p;
356 }
357 }
358
359 struct rb_node *
rb_node_prev(struct rb_node * node)360 rb_node_prev(struct rb_node *node)
361 {
362 if (node->left) {
363 /* If we have a left child, then the previous thing (compared to
364 * this node) is the right-most child of our left child.
365 */
366 return rb_node_maximum(node->left);
367 } else {
368 /* If node doesn't have a left child, crawl back up the to the
369 * right until we hit a parent to the left.
370 */
371 struct rb_node *p = rb_node_parent(node);
372 while (p && node == p->left) {
373 node = p;
374 p = rb_node_parent(node);
375 }
376 assert(p == NULL || node == p->right);
377 return p;
378 }
379 }
380
381 static void
validate_rb_node(struct rb_node * n,int black_depth)382 validate_rb_node(struct rb_node *n, int black_depth)
383 {
384 if (n == NULL) {
385 assert(black_depth == 0);
386 return;
387 }
388
389 if (rb_node_is_black(n)) {
390 black_depth--;
391 } else {
392 assert(rb_node_is_black(n->left));
393 assert(rb_node_is_black(n->right));
394 }
395
396 validate_rb_node(n->left, black_depth);
397 validate_rb_node(n->right, black_depth);
398 }
399
400 void
rb_tree_validate(struct rb_tree * T)401 rb_tree_validate(struct rb_tree *T)
402 {
403 if (T->root == NULL)
404 return;
405
406 assert(rb_node_is_black(T->root));
407
408 unsigned black_depth = 0;
409 for (struct rb_node *n = T->root; n; n = n->left) {
410 if (rb_node_is_black(n))
411 black_depth++;
412 }
413
414 validate_rb_node(T->root, black_depth);
415 }
416