|
|
1#ifndef ELEMENT_H__
2#define ELEMENT_H__ 1
3
4/* $Id: Element.h,v 1.1 2004/06/02 20:02:32 uwe Exp $ */
5
6typedef int Element;
7
8extern int compare(Element e1,
9 Element e2);
10
11#endif
|
|
1static char version[] =
2 "$Id: Element.c,v 1.1 2004/06/02 20:02:32 uwe Exp $";
3
4#include "Element.h"
5
6int
7compare(Element e1, Element e2)
8{
9 return (e1 >= e2) - (e2 >= e1);
10}
|
|
1#ifndef SET_H__
2#define SET_H__
3
4/* $Id: Set.h,v 1.1 2004/06/02 20:02:32 uwe Exp $ */
5
6/*--------------------*/
7
8#include "Element.h"
9
10typedef struct Node *Set;
11
12struct Node
13{
14 enum
15 { RED, BLACK } color;
16 Element info;
17 Set l;
18 Set r;
19};
20
21/*--------------------*/
22
23extern Set mkEmptySet(void);
24extern int isEmptySet(Set s);
25
26extern Set mkOneElemSet(Element e);
27extern Set insertElem(Element e, Set s);
28
29extern int isInSet(Element e, Set s);
30
31extern unsigned int card(Set s);
32
33extern unsigned int maxPathLength(Set
34 s);
35extern unsigned int minPathLength(Set
36 s);
37
38extern int invSetAsRedBlackTree(Set s);
39
40/*--------------------*/
41
42#endif
|
|
1static char version[] =
2 "$Id: Set.c,v 1.3 2006/01/31 18:27:51 uwe Exp $";
3
4#include "Set.h"
5
6#include <stdlib.h>
7#include <stdio.h>
8#include <assert.h>
9
10/*--------------------*/
11
12/* special empty node, marked as black */
13
14static struct Node finalNode = { BLACK };
15
16Set
17mkEmptySet(void)
18{
19 return &finalNode;
20}
21
22/* local optimization */
23
24#define mkEmptySet() (&finalNode)
25
26/*--------------------*/
27
28int
29isEmptySet(Set s)
30{
31 return s == &finalNode;
32}
33
34/* local optimization */
35
36#define isEmptySet(s) ((s) == &finalNode)
37
38/*--------------------*/
39
40/* auxiliary function: file scope */
41
42static Set
43mkNewRedNode(Element e)
44{
45 Set res = malloc(sizeof(*res));
46
47 if (!res)
48 {
49 perror
50 ("mkNewNode: malloc failed");
51 exit(1);
52 }
53
54 res->color = RED; /* every new node is red */
55 res->info = e;
56 res->l = mkEmptySet();
57 res->r = mkEmptySet();
58
59 return res;
60}
61
62/*--------------------*/
63
64Set
65mkOneElemSet(Element e)
66{
67 return insertElem(e, mkEmptySet());
68}
69
70/*--------------------*/
71
72int
73isInSet(Element e, Set s)
74{
75 if (isEmptySet(s))
76 return 0;
77
78 switch (compare(e, s->info))
79 {
80 case -1:
81 return isInSet(e, s->l);
82 case 0:
83 return 1;
84 case +1:
85 return isInSet(e, s->r);
86 }
87
88 assert(0);
89 return 0;
90}
91
92/*--------------------*/
93
94/* color predicates */
95
96#define isBlackNode(s) ((s)->color == BLACK)
97#define isRedNode(s) (! isBlackNode(s))
98
99static int
100hasRedChild(Set s)
101{
102 return
103 ! isEmptySet(s)
104 && (isRedNode(s->l)
105 ||
106 isRedNode(s->r));
107}
108
109/*--------------------*/
110
111/* reorganize tree */
112
113static Set
114balanceTrees(Set x, Set y, Set z,
115 Set b, Set c)
116{
117 x->r = b;
118 z->l = c;
119
120 y->l = x;
121 y->r = z;
122
123 x->color = BLACK;
124 z->color = BLACK;
125 y->color = RED;
126
127 return y;
128}
129
130/* check invariant */
131
132/* check balance in left subtree */
133
134static Set
135checkBalanceLeft(Set s)
136{
137 assert(!isEmptySet(s));
138
139 /* no balancing of trees with red root */
140
141 if (isRedNode(s))
142 return s;
143
144 if (isRedNode(s->l)
145 && isRedNode(s->l->l))
146 return balanceTrees(s->l->l,
147 s->l,
148 s,
149 s->l->l->r,
150 s->l->r);
151
152 if (isRedNode(s->l)
153 && isRedNode(s->l->r))
154 return balanceTrees(s->l,
155 s->l->r,
156 s,
157 s->l->r->l,
158 s->l->r->r);
159
160 return s;
161}
162
163/* check balance in right subtree */
164
165static Set
166checkBalanceRight(Set s)
167{
168 assert(!isEmptySet(s));
169
170 /* no balancing of trees with red root */
171
172 if (isRedNode(s))
173 return s;
174
175 if (isRedNode(s->r)
176 && isRedNode(s->r->l))
177 return balanceTrees(s,
178 s->r->l,
179 s->r,
180 s->r->l->l,
181 s->r->l->r);
182
183 if (isRedNode(s->r)
184 && isRedNode(s->r->r))
185 return balanceTrees(s,
186 s->r,
187 s->r->r,
188 s->r->l,
189 s->r->r->l);
190
191 return s;
192}
193
194/*--------------------*/
195
196static Set
197insertElem1(Element e, Set s)
198{
199 if (isEmptySet(s))
200 return mkNewRedNode(e);
201
202 switch (compare(e, s->info))
203 {
204 case -1:
205 s->l = insertElem1(e, s->l);
206
207 /* invariant is checked with left subtree */
208 return checkBalanceLeft(s);
209
210 case 0:
211 break;
212
213 case +1:
214 s->r = insertElem1(e, s->r);
215
216 /* invariant is checked with right subtree */
217 return checkBalanceRight(s);
218 }
219
220 return s;
221}
222
223/*--------------------*/
224
225Set
226insertElem(Element e, Set s)
227{
228 Set res = insertElem1(e, s);
229
230 /* the root is always black */
231
232 res->color = BLACK;
233
234 assert(invSetAsRedBlackTree(res));
235
236 return res;
237}
238
239/*--------------------*/
240
241static int
242lessThan(Set s, Element e)
243{
244 return
245 isEmptySet(s)
246 || (compare(s->info, e) == -1
247 && lessThan(s->r, e));
248
249}
250
251/*--------------------*/
252
253static int
254greaterThan(Set s, Element e)
255{
256 return
257 isEmptySet(s)
258 || (
259 compare(s->info, e) == +1
260 &&
261 greaterThan(s->l, e));
262}
263
264/*--------------------*/
265
266static int
267invSetAsBinTree(Set s)
268{
269 return
270 isEmptySet(s)
271 || (
272 lessThan(s->l, s->info)
273 &&
274 greaterThan(s->r, s->info)
275 &&
276 invSetAsBinTree(s->l)
277 &&
278 invSetAsBinTree(s->r));
279}
280
281/*--------------------*/
282
283static int
284invNoRedNodeHasRedChild(Set s)
285{
286 if (isEmptySet(s))
287 return 1;
288
289 return
290 (isBlackNode(s)
291 ||
292 ! hasRedChild(s)
293 )
294 &&
295 invNoRedNodeHasRedChild(s->l)
296 &&
297 invNoRedNodeHasRedChild(s->r);
298}
299
300/*--------------------*/
301
302static int
303noOfBlackNodes(Set s)
304{
305 if (isEmptySet(s))
306 return 1;
307
308 {
309 int nl = noOfBlackNodes(s->l);
310 int nr = noOfBlackNodes(s->r);
311
312 if (nl == nr && nl != -1)
313 return nl + isBlackNode(s);
314
315 /* invariant does not hold */
316 return -1;
317 }
318}
319
320/*--------------------*/
321
322int
323invSetAsRedBlackTree(Set s)
324{
325 return
326 invSetAsBinTree(s)
327 &&
328 invNoRedNodeHasRedChild(s)
329 &&
330 noOfBlackNodes(s) != -1;
331}
332
333/*--------------------*/
334
335unsigned int
336card(Set s)
337{
338 if (isEmptySet(s))
339 return 0;
340
341 return card(s->l) + 1 + card(s->r);
342}
343
344/*--------------------*/
345
346static unsigned int
347max(unsigned int i, unsigned int j)
348{
349 return i > j ? i : j;
350}
351
352/*--------------------*/
353
354static unsigned int
355min(unsigned int i, unsigned int j)
356{
357 return i < j ? i : j;
358}
359
360/*--------------------*/
361
362unsigned int
363maxPathLength(Set s)
364{
365 if (isEmptySet(s))
366 return 0;
367
368 return
369 1 + max(maxPathLength(s->l),
370 maxPathLength(s->r));
371}
372
373/*--------------------*/
374
375unsigned int
376minPathLength(Set s)
377{
378 if (isEmptySet(s))
379 return 0;
380
381 return
382 1 + min(minPathLength(s->l),
383 minPathLength(s->r));
384}
385
386/*--------------------*/
|
|
1#include <stdio.h>
2#include <assert.h>
3
4#include "Element.h"
5#include "Set.h"
6
7int
8main(int argc, char *argv[])
9{
10 unsigned int noOfElems = 1000;
11
12 if (argc == 2)
13 sscanf(argv[1], "%u", &noOfElems);
14
15 fprintf(stderr,
16 "%s %u %s",
17 "run red black trees with inserting",
18 noOfElems,
19 "elements in ascending order\n"
20 );
21
22 {
23 Set s = mkEmptySet();
24 unsigned int i;
25
26 for (i = 0; i < noOfElems; ++i)
27 {
28 s = insertElem((Element) i, s);
29 }
30
31 fprintf(stderr,
32 "card(s) = %u\n",
33 card(s));
34 fprintf(stderr,
35 "minPathLength(s) = %u\n",
36 minPathLength(s));
37 fprintf(stderr,
38 "maxPathLength(s) = %u\n",
39 maxPathLength(s));
40 }
41
42 return 0;
43}
|
| Letzte Änderung: 04.01.2011 | © Prof. Dr. Uwe Schmidt |