aboutsummaryrefslogtreecommitdiff
path: root/rb.c
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2020-07-26 10:50:06 +0200
committerThomas Schmucker <ts@its1.de>2020-07-26 10:50:06 +0200
commit1aecbf40567f0f1943285c774b4d6369e1a90ceb (patch)
tree0139ee67feff2958b6837858caf369c8b3d6296a /rb.c
parent606af049dab5caf4ff58075c20b215071a0cb3fd (diff)
downloaddata-structures-1aecbf40567f0f1943285c774b4d6369e1a90ceb.tar.gz
data-structures-1aecbf40567f0f1943285c774b4d6369e1a90ceb.tar.bz2
data-structures-1aecbf40567f0f1943285c774b4d6369e1a90ceb.zip
Code Cleanup für Red-Black-Trees
Diffstat (limited to 'rb.c')
-rw-r--r--rb.c1018
1 files changed, 483 insertions, 535 deletions
diff --git a/rb.c b/rb.c
index c95ab83..2a8bff2 100644
--- a/rb.c
+++ b/rb.c
@@ -1,158 +1,8 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <stdlib.h> 2#include <stdlib.h>
3#include <time.h> 3#include <time.h>
4#include "util.h"
5
6typedef int T;
7
8#if 0
9struct rbtree {
10 T data;
11 enum { RED, BLACK } color;
12 struct rbtree *left, *right, *p;
13};
14
15struct rbtree *
16rb_alloc(T data)
17{
18 struct rbtree *node = malloc(sizeof *node);
19 if ( node )
20 {
21 node->data = data;
22 node->left = NULL;
23 node->right = NULL;
24 node->p = NULL;
25 }
26 return node;
27}
28
29void
30rb_left_rotate(struct rbtree **root, struct rbtree *x)
31{
32 struct rbtree *y = x->right;
33 x->right = y->left;
34 if ( y->left )
35 y->left->p = x;
36
37 y->p = x->p;
38 if ( x->p == NULL )
39 *root = y;
40 else if ( x == x->p->left )
41 x->p->left = y;
42 else
43 x->p->right = y;
44
45 y->left = x;
46 x->p = y;
47}
48
49void
50rb_right_rotate(struct rbtree **root, struct rbtree *y)
51{
52 struct rbtree *x = y->left;
53 y->left = x->right;
54 if ( x->right )
55 x->right->p = y;
56
57 x->p = y->p;
58 if ( y->p == NULL )
59 *root = x;
60 else if ( y == y->p->left )
61 y->p->left = x;
62 else
63 y->p->right = x;
64
65 x->right = y;
66 y->p = x;
67}
68
69void
70rb_insert_fixup(struct rbtree **root, struct rbtree **z)
71{
72 struct rbtree *y;
73
74 while ( z->p->color == RED ) {
75 if ( z->p == z->p->p->left ) {
76 y = z->p->p->right;
77 if ( y->color == RED ) {
78 z->p->color = BLACK;
79 y->color = BLACK;
80 z->p->p->color = RED;
81 z = z->p->p;
82 }
83 else {
84 if ( z == z->p->right ) {
85 z = z->p;
86 rb_left_rotate(root, z);
87 }
88 z->p->color = BLACK;
89 z->p->p->color = RED;
90 rb_right_rotate(root, z->p->p);
91 }
92 }
93 else {
94 y = z->p->p->left;
95 if ( y->color == RED ) {
96 z->p->color = BLACK;
97 y->color = BLACK;
98 z->p->p->color = RED;
99 z = z->p->p;
100 }
101 else {
102 if ( z == z->p->left ) {
103 z = z->p;
104 rb_right_rotate(root, z);
105 }
106 z->p->color = BLACK;
107 z->p->p->color = RED;
108 rb_left_rotate(root, z->p->p);
109 }
110 }
111 }
112
113 (*root)->color = BLACK;
114}
115
116void
117rb_insert_node(struct rbtree **root, T data)
118{
119 struct rbtree *z = rb_alloc(data);
120
121 if ( *root == NULL ) {
122 z->color = BLACK;
123 *root = z;
124 }
125 else {
126 struct rbtree *y = NULL;
127 struct rbtree *x = *root;
128
129 while ( x ) {
130 y = x;
131 if ( z->data < x->data )
132 x = x->left;
133 else
134 x = x->right;
135 }
136 z->p = y;
137
138 if ( y == NULL ) // kann entfallen!
139 *root = z;
140 else if ( z->data < y->data )
141 y->left = z;
142 else
143 y->right = z;
144
145 z->left = NULL; // kann entfallen!
146 z->right = NULL; // kann entfallen!
147 z->color = RED;
148
149 rb_insert_fixup(root, &z);
150 }
151}
152
153#endif
154
155 4
5#include "util.h"
156 6
157/* The authors of this work have released all rights to it and placed it 7/* The authors of this work have released all rights to it and placed it
158in the public domain under the Creative Commons CC0 1.0 waiver 8in the public domain under the Creative Commons CC0 1.0 waiver
@@ -169,48 +19,48 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
169Retrieved from: http://en.literateprograms.org/Red-black_tree_(C)?oldid=19567 19Retrieved from: http://en.literateprograms.org/Red-black_tree_(C)?oldid=19567
170*/ 20*/
171 21
172enum rbtree_node_color { RED, BLACK }; 22enum rbtree_node_color { RED,
23 BLACK };
173 24
174typedef struct rbtree_node_t { 25typedef struct rbtree_node_t {
175void* key; 26 void * key;
176void* value; 27 void * value;
177struct rbtree_node_t* left; 28 struct rbtree_node_t * left;
178struct rbtree_node_t* right; 29 struct rbtree_node_t * right;
179struct rbtree_node_t* parent; 30 struct rbtree_node_t * parent;
180enum rbtree_node_color color; 31 enum rbtree_node_color color;
181} *rbtree_node; 32} * rbtree_node;
182 33
183typedef struct rbtree_t { 34typedef struct rbtree_t {
184rbtree_node root; 35 rbtree_node root;
185} *rbtree; 36} * rbtree;
186 37
187typedef int (*compare_func)(void* left, void* right); 38typedef int (*compare_func)(void *left, void *right);
188 39
189rbtree rbtree_create(); 40rbtree rbtree_create();
190void* rbtree_lookup(rbtree t, void* key, compare_func compare); 41void * rbtree_lookup(rbtree t, void *key, compare_func compare);
191void rbtree_insert(rbtree t, void* key, void* value, compare_func compare); 42void rbtree_insert(rbtree t, void *key, void *value, compare_func compare);
192void rbtree_delete(rbtree t, void* key, compare_func compare); 43void rbtree_delete(rbtree t, void *key, compare_func compare);
193
194 44
195#include <assert.h> 45#include <assert.h>
196#include <stdlib.h> 46#include <stdlib.h>
197 47
198typedef rbtree_node node; 48typedef rbtree_node node;
199typedef enum rbtree_node_color color; 49typedef enum rbtree_node_color color;
200 50
201static node grandparent(node n); 51static node grandparent(node n);
202static node sibling(node n); 52static node sibling(node n);
203static node uncle(node n); 53static node uncle(node n);
204static void verify_properties(rbtree t); 54static void verify_properties(rbtree t);
205static void verify_property_1(node root); 55static void verify_property_1(node root);
206static void verify_property_2(node root); 56static void verify_property_2(node root);
207static color node_color(node n); 57static color node_color(node n);
208static void verify_property_4(node root); 58static void verify_property_4(node root);
209static void verify_property_5(node root); 59static void verify_property_5(node root);
210static void verify_property_5_helper(node n, int black_count, int* black_count_path); 60static void verify_property_5_helper(node n, int black_count, int *black_count_path);
211 61
212static node new_node(void* key, void* value, color node_color, node left, node right); 62static node new_node(void *key, void *value, color node_color, node left, node right);
213static node lookup_node(rbtree t, void* key, compare_func compare); 63static node lookup_node(rbtree t, void *key, compare_func compare);
214static void rotate_left(rbtree t, node n); 64static void rotate_left(rbtree t, node n);
215static void rotate_right(rbtree t, node n); 65static void rotate_right(rbtree t, node n);
216 66
@@ -228,334 +78,434 @@ static void delete_case4(rbtree t, node n);
228static void delete_case5(rbtree t, node n); 78static void delete_case5(rbtree t, node n);
229static void delete_case6(rbtree t, node n); 79static void delete_case6(rbtree t, node n);
230 80
231node grandparent(node n) { 81node
232 assert (n != NULL); 82grandparent(node n)
233 assert (n->parent != NULL); /* Not the root node */ 83{
234 assert (n->parent->parent != NULL); /* Not child of root */ 84 assert(n != NULL);
235 return n->parent->parent; 85 assert(n->parent != NULL); /* Not the root node */
86 assert(n->parent->parent != NULL); /* Not child of root */
87 return n->parent->parent;
236} 88}
237node sibling(node n) { 89
238 assert (n != NULL); 90node
239 assert (n->parent != NULL); /* Root node has no sibling */ 91sibling(node n)
240 if (n == n->parent->left) 92{
241 return n->parent->right; 93 assert(n != NULL);
242 else 94 assert(n->parent != NULL); /* Root node has no sibling */
243 return n->parent->left; 95 if ( n == n->parent->left )
96 return n->parent->right;
97 else
98 return n->parent->left;
244} 99}
245node uncle(node n) { 100
246 assert (n != NULL); 101node
247 assert (n->parent != NULL); /* Root node has no uncle */ 102uncle(node n)
248 assert (n->parent->parent != NULL); /* Children of root have no uncle */ 103{
249 return sibling(n->parent); 104 assert(n != NULL);
105 assert(n->parent != NULL); /* Root node has no uncle */
106 assert(n->parent->parent != NULL); /* Children of root have no uncle */
107 return sibling(n->parent);
250} 108}
251void verify_properties(rbtree t) { 109
110void
111verify_properties(rbtree t)
112{
252#ifdef VERIFY_RBTREE 113#ifdef VERIFY_RBTREE
253 verify_property_1(t->root); 114 verify_property_1(t->root);
254 verify_property_2(t->root); 115 verify_property_2(t->root);
255 /* Property 3 is implicit */ 116 /* Property 3 is implicit */
256 verify_property_4(t->root); 117 verify_property_4(t->root);
257 verify_property_5(t->root); 118 verify_property_5(t->root);
258#endif 119#endif
259} 120}
260void verify_property_1(node n) { 121
261 assert(node_color(n) == RED || node_color(n) == BLACK); 122void
262 if (n == NULL) return; 123verify_property_1(node n)
263 verify_property_1(n->left); 124{
264 verify_property_1(n->right); 125 assert(node_color(n) == RED || node_color(n) == BLACK);
126 if ( n == NULL )
127 return;
128 verify_property_1(n->left);
129 verify_property_1(n->right);
265} 130}
266void verify_property_2(node root) { 131
267 assert(node_color(root) == BLACK); 132void
133verify_property_2(node root)
134{
135 assert(node_color(root) == BLACK);
268} 136}
269color node_color(node n) { 137
270 return n == NULL ? BLACK : n->color; 138color
139node_color(node n)
140{
141 return n == NULL ? BLACK : n->color;
271} 142}
272void verify_property_4(node n) { 143
273 if (node_color(n) == RED) { 144void
274 assert (node_color(n->left) == BLACK); 145verify_property_4(node n)
275 assert (node_color(n->right) == BLACK); 146{
276 assert (node_color(n->parent) == BLACK); 147 if ( node_color(n) == RED ) {
277 } 148 assert(node_color(n->left) == BLACK);
278 if (n == NULL) return; 149 assert(node_color(n->right) == BLACK);
279 verify_property_4(n->left); 150 assert(node_color(n->parent) == BLACK);
280 verify_property_4(n->right); 151 }
152 if ( n == NULL )
153 return;
154 verify_property_4(n->left);
155 verify_property_4(n->right);
281} 156}
282void verify_property_5(node root) { 157
283 int black_count_path = -1; 158void
284 verify_property_5_helper(root, 0, &black_count_path); 159verify_property_5(node root)
160{
161 int black_count_path = -1;
162 verify_property_5_helper(root, 0, &black_count_path);
285} 163}
286 164
287void verify_property_5_helper(node n, int black_count, int* path_black_count) { 165void
288 if (node_color(n) == BLACK) { 166verify_property_5_helper(node n, int black_count, int *path_black_count)
289 black_count++; 167{
290 } 168 if ( node_color(n) == BLACK ) {
291 if (n == NULL) { 169 black_count++;
292 if (*path_black_count == -1) { 170 }
293 *path_black_count = black_count; 171 if ( n == NULL ) {
294 } else { 172 if ( *path_black_count == -1 ) {
295 assert (black_count == *path_black_count); 173 *path_black_count = black_count;
296 } 174 }
297 return; 175 else {
298 } 176 assert(black_count == *path_black_count);
299 verify_property_5_helper(n->left, black_count, path_black_count); 177 }
300 verify_property_5_helper(n->right, black_count, path_black_count); 178 return;
179 }
180 verify_property_5_helper(n->left, black_count, path_black_count);
181 verify_property_5_helper(n->right, black_count, path_black_count);
301} 182}
302rbtree rbtree_create() { 183
303 rbtree t = malloc(sizeof(struct rbtree_t)); 184rbtree
304 t->root = NULL; 185rbtree_create()
305 verify_properties(t); 186{
306 return t; 187 rbtree t = malloc(sizeof(struct rbtree_t));
188 t->root = NULL;
189 verify_properties(t);
190 return t;
307} 191}
308node new_node(void* key, void* value, color node_color, node left, node right) { 192
309 node result = malloc(sizeof(struct rbtree_node_t)); 193node
310 result->key = key; 194new_node(void *key, void *value, color node_color, node left, node right)
311 result->value = value; 195{
312 result->color = node_color; 196 node result = malloc(sizeof(struct rbtree_node_t));
313 result->left = left; 197 result->key = key;
314 result->right = right; 198 result->value = value;
315 if (left != NULL) left->parent = result; 199 result->color = node_color;
316 if (right != NULL) right->parent = result; 200 result->left = left;
317 result->parent = NULL; 201 result->right = right;
318 return result; 202 if ( left != NULL )
203 left->parent = result;
204 if ( right != NULL )
205 right->parent = result;
206 result->parent = NULL;
207 return result;
319} 208}
320node lookup_node(rbtree t, void* key, compare_func compare) { 209
321 node n = t->root; 210node
322 while (n != NULL) { 211lookup_node(rbtree t, void *key, compare_func compare)
323 int comp_result = compare(key, n->key); 212{
324 if (comp_result == 0) { 213 node n = t->root;
325 return n; 214 while ( n != NULL ) {
326 } else if (comp_result < 0) { 215 int comp_result = compare(key, n->key);
327 n = n->left; 216 if ( comp_result == 0 ) {
328 } else { 217 return n;
329 assert(comp_result > 0); 218 }
330 n = n->right; 219 else if ( comp_result < 0 ) {
331 } 220 n = n->left;
332 } 221 }
333 return n; 222 else {
223 assert(comp_result > 0);
224 n = n->right;
225 }
226 }
227 return n;
334} 228}
335void* rbtree_lookup(rbtree t, void* key, compare_func compare) { 229
336 node n = lookup_node(t, key, compare); 230void *
337 return n == NULL ? NULL : n->value; 231rbtree_lookup(rbtree t, void *key, compare_func compare)
232{
233 node n = lookup_node(t, key, compare);
234 return n == NULL ? NULL : n->value;
338} 235}
339void rotate_left(rbtree t, node n) { 236
340 node r = n->right; 237void
341 replace_node(t, n, r); 238rotate_left(rbtree t, node n)
342 n->right = r->left; 239{
343 if (r->left != NULL) { 240 node r = n->right;
344 r->left->parent = n; 241 replace_node(t, n, r);
345 } 242 n->right = r->left;
346 r->left = n; 243 if ( r->left != NULL ) {
347 n->parent = r; 244 r->left->parent = n;
245 }
246 r->left = n;
247 n->parent = r;
348} 248}
349 249
350void rotate_right(rbtree t, node n) { 250void
351 node L = n->left; 251rotate_right(rbtree t, node n)
352 replace_node(t, n, L); 252{
353 n->left = L->right; 253 node L = n->left;
354 if (L->right != NULL) { 254 replace_node(t, n, L);
355 L->right->parent = n; 255 n->left = L->right;
356 } 256 if ( L->right != NULL ) {
357 L->right = n; 257 L->right->parent = n;
358 n->parent = L; 258 }
259 L->right = n;
260 n->parent = L;
359} 261}
360void replace_node(rbtree t, node oldn, node newn) { 262
361 if (oldn->parent == NULL) { 263void
362 t->root = newn; 264replace_node(rbtree t, node oldn, node newn)
363 } else { 265{
364 if (oldn == oldn->parent->left) 266 if ( oldn->parent == NULL ) {
365 oldn->parent->left = newn; 267 t->root = newn;
366 else 268 }
367 oldn->parent->right = newn; 269 else {
368 } 270 if ( oldn == oldn->parent->left )
369 if (newn != NULL) { 271 oldn->parent->left = newn;
370 newn->parent = oldn->parent; 272 else
371 } 273 oldn->parent->right = newn;
274 }
275 if ( newn != NULL ) {
276 newn->parent = oldn->parent;
277 }
372} 278}
373void rbtree_insert(rbtree t, void* key, void* value, compare_func compare) { 279
374 node inserted_node = new_node(key, value, RED, NULL, NULL); 280void
375 if (t->root == NULL) { 281rbtree_insert(rbtree t, void *key, void *value, compare_func compare)
376 t->root = inserted_node; 282{
377 } else { 283 node inserted_node = new_node(key, value, RED, NULL, NULL);
378 node n = t->root; 284 if ( t->root == NULL ) {
379 while (1) { 285 t->root = inserted_node;
380 int comp_result = compare(key, n->key); 286 }
381 if (comp_result == 0) { 287 else {
382 n->value = value; 288 node n = t->root;
383 return; 289 while ( 1 ) {
384 } else if (comp_result < 0) { 290 int comp_result = compare(key, n->key);
385 if (n->left == NULL) { 291 if ( comp_result == 0 ) {
386 n->left = inserted_node; 292 n->value = value;
387 break; 293 return;
388 } else { 294 }
389 n = n->left; 295 else if ( comp_result < 0 ) {
390 } 296 if ( n->left == NULL ) {
391 } else { 297 n->left = inserted_node;
392 assert (comp_result > 0); 298 break;
393 if (n->right == NULL) { 299 }
394 n->right = inserted_node; 300 else {
395 break; 301 n = n->left;
396 } else { 302 }
397 n = n->right; 303 }
398 } 304 else {
399 } 305 assert(comp_result > 0);
400 } 306 if ( n->right == NULL ) {
401 inserted_node->parent = n; 307 n->right = inserted_node;
402 } 308 break;
403 insert_case1(t, inserted_node); 309 }
404 verify_properties(t); 310 else {
311 n = n->right;
312 }
313 }
314 }
315 inserted_node->parent = n;
316 }
317 insert_case1(t, inserted_node);
318 verify_properties(t);
405} 319}
406void insert_case1(rbtree t, node n) { 320
407 if (n->parent == NULL) 321void
408 n->color = BLACK; 322insert_case1(rbtree t, node n)
409 else 323{
410 insert_case2(t, n); 324 if ( n->parent == NULL )
325 n->color = BLACK;
326 else
327 insert_case2(t, n);
411} 328}
412void insert_case2(rbtree t, node n) { 329
413 if (node_color(n->parent) == BLACK) 330void
414 return; /* Tree is still valid */ 331insert_case2(rbtree t, node n)
415 else 332{
416 insert_case3(t, n); 333 if ( node_color(n->parent) == BLACK )
334 return; /* Tree is still valid */
335 else
336 insert_case3(t, n);
417} 337}
418void insert_case3(rbtree t, node n) { 338
419 if (node_color(uncle(n)) == RED) { 339void
420 n->parent->color = BLACK; 340insert_case3(rbtree t, node n)
421 uncle(n)->color = BLACK; 341{
422 grandparent(n)->color = RED; 342 if ( node_color(uncle(n)) == RED ) {
423 insert_case1(t, grandparent(n)); 343 n->parent->color = BLACK;
424 } else { 344 uncle(n)->color = BLACK;
425 insert_case4(t, n); 345 grandparent(n)->color = RED;
426 } 346 insert_case1(t, grandparent(n));
347 }
348 else {
349 insert_case4(t, n);
350 }
427} 351}
428void insert_case4(rbtree t, node n) { 352
429 if (n == n->parent->right && n->parent == grandparent(n)->left) { 353void
430 rotate_left(t, n->parent); 354insert_case4(rbtree t, node n)
431 n = n->left; 355{
432 } else if (n == n->parent->left && n->parent == grandparent(n)->right) { 356 if ( n == n->parent->right && n->parent == grandparent(n)->left ) {
433 rotate_right(t, n->parent); 357 rotate_left(t, n->parent);
434 n = n->right; 358 n = n->left;
435 } 359 }
436 insert_case5(t, n); 360 else if ( n == n->parent->left && n->parent == grandparent(n)->right ) {
361 rotate_right(t, n->parent);
362 n = n->right;
363 }
364 insert_case5(t, n);
437} 365}
438void insert_case5(rbtree t, node n) { 366
439 n->parent->color = BLACK; 367void
440 grandparent(n)->color = RED; 368insert_case5(rbtree t, node n)
441 if (n == n->parent->left && n->parent == grandparent(n)->left) { 369{
442 rotate_right(t, grandparent(n)); 370 n->parent->color = BLACK;
443 } else { 371 grandparent(n)->color = RED;
444 assert (n == n->parent->right && n->parent == grandparent(n)->right); 372 if ( n == n->parent->left && n->parent == grandparent(n)->left ) {
445 rotate_left(t, grandparent(n)); 373 rotate_right(t, grandparent(n));
446 } 374 }
375 else {
376 assert(n == n->parent->right && n->parent == grandparent(n)->right);
377 rotate_left(t, grandparent(n));
378 }
447} 379}
448void rbtree_delete(rbtree t, void* key, compare_func compare) {
449 node child;
450 node n = lookup_node(t, key, compare);
451 if (n == NULL) return; /* Key not found, do nothing */
452 if (n->left != NULL && n->right != NULL) {
453 /* Copy key/value from predecessor and then delete it instead */
454 node pred = maximum_node(n->left);
455 n->key = pred->key;
456 n->value = pred->value;
457 n = pred;
458 }
459 380
460 assert(n->left == NULL || n->right == NULL); 381void
461 child = n->right == NULL ? n->left : n->right; 382rbtree_delete(rbtree t, void *key, compare_func compare)
462 if (node_color(n) == BLACK) { 383{
463 n->color = node_color(child); 384 node child;
464 delete_case1(t, n); 385 node n = lookup_node(t, key, compare);
465 } 386 if ( n == NULL )
466 replace_node(t, n, child); 387 return; /* Key not found, do nothing */
467 if (n->parent == NULL && child != NULL) // root should be black 388 if ( n->left != NULL && n->right != NULL ) {
468 child->color = BLACK; 389 /* Copy key/value from predecessor and then delete it instead */
469 free(n); 390 node pred = maximum_node(n->left);
391 n->key = pred->key;
392 n->value = pred->value;
393 n = pred;
394 }
470 395
471 verify_properties(t); 396 assert(n->left == NULL || n->right == NULL);
472} 397 child = n->right == NULL ? n->left : n->right;
473static node maximum_node(node n) { 398 if ( node_color(n) == BLACK ) {
474 assert (n != NULL); 399 n->color = node_color(child);
475 while (n->right != NULL) { 400 delete_case1(t, n);
476 n = n->right; 401 }
477 } 402 replace_node(t, n, child);
478 return n; 403 if ( n->parent == NULL && child != NULL ) // root should be black
479} 404 child->color = BLACK;
480void delete_case1(rbtree t, node n) { 405 free(n);
481 if (n->parent == NULL) 406
482 return; 407 verify_properties(t);
483 else
484 delete_case2(t, n);
485} 408}
486void delete_case2(rbtree t, node n) { 409
487 if (node_color(sibling(n)) == RED) { 410static node
488 n->parent->color = RED; 411maximum_node(node n)
489 sibling(n)->color = BLACK; 412{
490 if (n == n->parent->left) 413 assert(n != NULL);
491 rotate_left(t, n->parent); 414 while ( n->right != NULL ) {
492 else 415 n = n->right;
493 rotate_right(t, n->parent); 416 }
494 } 417 return n;
495 delete_case3(t, n);
496} 418}
497void delete_case3(rbtree t, node n) { 419
498 if (node_color(n->parent) == BLACK && 420void
499 node_color(sibling(n)) == BLACK && 421delete_case1(rbtree t, node n)
500 node_color(sibling(n)->left) == BLACK && 422{
501 node_color(sibling(n)->right) == BLACK) 423 if ( n->parent == NULL )
502 { 424 return;
503 sibling(n)->color = RED; 425 else
504 delete_case1(t, n->parent); 426 delete_case2(t, n);
505 }
506 else
507 delete_case4(t, n);
508} 427}
509void delete_case4(rbtree t, node n) { 428
510 if (node_color(n->parent) == RED && 429void
511 node_color(sibling(n)) == BLACK && 430delete_case2(rbtree t, node n)
512 node_color(sibling(n)->left) == BLACK && 431{
513 node_color(sibling(n)->right) == BLACK) 432 if ( node_color(sibling(n)) == RED ) {
514 { 433 n->parent->color = RED;
515 sibling(n)->color = RED; 434 sibling(n)->color = BLACK;
516 n->parent->color = BLACK; 435 if ( n == n->parent->left )
517 } 436 rotate_left(t, n->parent);
518 else 437 else
519 delete_case5(t, n); 438 rotate_right(t, n->parent);
439 }
440 delete_case3(t, n);
520} 441}
521void delete_case5(rbtree t, node n) { 442
522 if (n == n->parent->left && 443void
523 node_color(sibling(n)) == BLACK && 444delete_case3(rbtree t, node n)
524 node_color(sibling(n)->left) == RED && 445{
525 node_color(sibling(n)->right) == BLACK) 446 if ( node_color(n->parent) == BLACK &&
526 { 447 node_color(sibling(n)) == BLACK &&
527 sibling(n)->color = RED; 448 node_color(sibling(n)->left) == BLACK &&
528 sibling(n)->left->color = BLACK; 449 node_color(sibling(n)->right) == BLACK ) {
529 rotate_right(t, sibling(n)); 450 sibling(n)->color = RED;
530 } 451 delete_case1(t, n->parent);
531 else if (n == n->parent->right && 452 }
532 node_color(sibling(n)) == BLACK && 453 else
533 node_color(sibling(n)->right) == RED && 454 delete_case4(t, n);
534 node_color(sibling(n)->left) == BLACK)
535 {
536 sibling(n)->color = RED;
537 sibling(n)->right->color = BLACK;
538 rotate_left(t, sibling(n));
539 }
540 delete_case6(t, n);
541} 455}
542void delete_case6(rbtree t, node n) { 456
543 sibling(n)->color = node_color(n->parent); 457void
544 n->parent->color = BLACK; 458delete_case4(rbtree t, node n)
545 if (n == n->parent->left) { 459{
546 assert (node_color(sibling(n)->right) == RED); 460 if ( node_color(n->parent) == RED &&
547 sibling(n)->right->color = BLACK; 461 node_color(sibling(n)) == BLACK &&
548 rotate_left(t, n->parent); 462 node_color(sibling(n)->left) == BLACK &&
549 } 463 node_color(sibling(n)->right) == BLACK ) {
550 else 464 sibling(n)->color = RED;
551 { 465 n->parent->color = BLACK;
552 assert (node_color(sibling(n)->left) == RED); 466 }
553 sibling(n)->left->color = BLACK; 467 else
554 rotate_right(t, n->parent); 468 delete_case5(t, n);
555 }
556} 469}
557 470
471void
472delete_case5(rbtree t, node n)
473{
474 if ( n == n->parent->left &&
475 node_color(sibling(n)) == BLACK &&
476 node_color(sibling(n)->left) == RED &&
477 node_color(sibling(n)->right) == BLACK ) {
478 sibling(n)->color = RED;
479 sibling(n)->left->color = BLACK;
480 rotate_right(t, sibling(n));
481 }
482 else if ( n == n->parent->right &&
483 node_color(sibling(n)) == BLACK &&
484 node_color(sibling(n)->right) == RED &&
485 node_color(sibling(n)->left) == BLACK ) {
486 sibling(n)->color = RED;
487 sibling(n)->right->color = BLACK;
488 rotate_left(t, sibling(n));
489 }
490 delete_case6(t, n);
491}
558 492
493void
494delete_case6(rbtree t, node n)
495{
496 sibling(n)->color = node_color(n->parent);
497 n->parent->color = BLACK;
498 if ( n == n->parent->left ) {
499 assert(node_color(sibling(n)->right) == RED);
500 sibling(n)->right->color = BLACK;
501 rotate_left(t, n->parent);
502 }
503 else {
504 assert(node_color(sibling(n)->left) == RED);
505 sibling(n)->left->color = BLACK;
506 rotate_right(t, n->parent);
507 }
508}
559 509
560/* The authors of this work have released all rights to it and placed it 510/* The authors of this work have released all rights to it and placed it
561in the public domain under the Creative Commons CC0 1.0 waiver 511in the public domain under the Creative Commons CC0 1.0 waiver
@@ -572,90 +522,88 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
572Retrieved from: http://en.literateprograms.org/Red-black_tree_(C)?oldid=19567 522Retrieved from: http://en.literateprograms.org/Red-black_tree_(C)?oldid=19567
573*/ 523*/
574 524
575#include <stdio.h>
576#include <assert.h> 525#include <assert.h>
526#include <stdio.h>
577#include <stdlib.h> /* rand() */ 527#include <stdlib.h> /* rand() */
578 528
579static int compare_int(void* left, void* right); 529static int compare_int(void *left, void *right);
580static void print_tree(rbtree t); 530static void print_tree(rbtree t);
581static void print_tree_helper(rbtree_node n, int indent); 531static void print_tree_helper(rbtree_node n, int indent);
582 532
583int compare_int(void* leftp, void* rightp) { 533int
584 int left = (int)leftp; 534compare_int(void *leftp, void *rightp)
585 int right = (int)rightp; 535{
586 if (left < right) 536 int left = (int) leftp;
587 return -1; 537 int right = (int) rightp;
588 else if (left > right) 538 if ( left < right )
589 return 1; 539 return -1;
590 else { 540 else if ( left > right )
591 assert (left == right); 541 return 1;
592 return 0; 542 else {
593 } 543 assert(left == right);
544 return 0;
545 }
594} 546}
595 547
596#define INDENT_STEP 4 548#define INDENT_STEP 4
597 549
598void print_tree_helper(rbtree_node n, int indent); 550void print_tree_helper(rbtree_node n, int indent);
599 551
600void print_tree(rbtree t) { 552void
601 print_tree_helper(t->root, 0); 553print_tree(rbtree t)
602 puts(""); 554{
555 print_tree_helper(t->root, 0);
556 puts("");
603} 557}
604 558
605void print_tree_helper(rbtree_node n, int indent) { 559void
606 int i; 560print_tree_helper(rbtree_node n, int indent)
607 if (n == NULL) { 561{
608 fputs("<empty tree>", stdout); 562 int i;
609 return; 563 if ( n == NULL ) {
610 } 564 fputs("<empty tree>", stdout);
611 if (n->right != NULL) { 565 return;
612 print_tree_helper(n->right, indent + INDENT_STEP); 566 }
613 } 567 if ( n->right != NULL ) {
614 for(i=0; i<indent; i++) 568 print_tree_helper(n->right, indent + INDENT_STEP);
615 fputs(" ", stdout); 569 }
616 if (n->color == BLACK) 570 for ( i = 0; i < indent; i++ )
617 printf("%d\n", (int)n->key); 571 fputs(" ", stdout);
618 else 572 if ( n->color == BLACK )
619 printf("<%d>\n", (int)n->key); 573 printf("%d\n", (int) n->key);
620 if (n->left != NULL) { 574 else
621 print_tree_helper(n->left, indent + INDENT_STEP); 575 printf("<%d>\n", (int) n->key);
622 } 576 if ( n->left != NULL ) {
577 print_tree_helper(n->left, indent + INDENT_STEP);
578 }
623} 579}
624 580
625int main() { 581int
626 int i; 582main()
627 rbtree t = rbtree_create(); 583{
628 print_tree(t); 584 int i;
585 rbtree t = rbtree_create();
629 586
630 for(i=0; i<5000; i++) { 587 for ( i = 0; i < 50; i++ ) {
631 long x = rand() % 10000; 588 long x = rand() % 10000;
632 long y = rand() % 10000; 589 long y = rand() % 10000;
633#ifdef TRACE 590#ifdef TRACE
634 print_tree(t); 591 print_tree(t);
635 printf("Inserting %d -> %d\n\n", x, y); 592 printf("Inserting %ld -> %ld\n\n", x, y);
636#endif 593#endif
637 rbtree_insert(t, (void*)x, (void*)y, compare_int); 594 rbtree_insert(t, (void *) x, (void *) y, compare_int);
638 assert(rbtree_lookup(t, (void*)x, compare_int) == (void*)y); 595 assert(rbtree_lookup(t, (void *) x, compare_int) == (void *) y);
639 } 596 }
640 for(i=0; i<60000; i++) {
641 long x = rand() % 10000;
642#ifdef TRACE
643 print_tree(t);
644 printf("Deleting key %d\n\n", x);
645#endif
646 rbtree_delete(t, (void*)x, compare_int);
647 }
648 return 0;
649}
650
651#if 0
652int main__(void)
653{
654 struct rbtree *tree = NULL;
655 597
656 srand(time(NULL)); 598 print_tree(t);
657 for ( int i = 0; i != 10; ++i )
658 rb_insert_node(&tree, rand());
659 599
660} 600 for ( i = 0; i < 60000; i++ ) {
601 long x = rand() % 10000;
602#ifdef TRACE
603 print_tree(t);
604 printf("Deleting key %ld\n\n", x);
661#endif 605#endif
606 rbtree_delete(t, (void *) x, compare_int);
607 }
608 return 0;
609}