1 /* Copyright (c) 2007-2008 Massachusetts Institute of Technology
3 * Permission is hereby granted, free of charge, to any person obtaining
4 * a copy of this software and associated documentation files (the
5 * "Software"), to deal in the Software without restriction, including
6 * without limitation the rights to use, copy, modify, merge, publish,
7 * distribute, sublicense, and/or sell copies of the Software, and to
8 * permit persons to whom the Software is furnished to do so, subject to
9 * the following conditions:
11 * The above copyright notice and this permission notice shall be
12 * included in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 static int comp(rb_key k1, rb_key k2)
31 if (*k1 < *k2) return -1;
32 if (*k1 > *k2) return +1;
36 int main(int argc, char **argv)
46 fprintf(stderr, "Usage: redblack_test Ntest [rand seed]\n");
51 k = (int *) malloc(N * sizeof(int));
52 rb_tree_init(&t, comp);
54 srand((unsigned) (argc > 2 ? atoi(argv[2]) : time(NULL)));
55 for (i = 0; i < N; ++i) {
56 double *newk = (double *) malloc(sizeof(double));
57 *newk = (k[i] = rand() % N);
58 if (!rb_tree_insert(&t, newk)) {
59 fprintf(stderr, "error in rb_tree_insert\n");
62 if (!rb_tree_check(&t)) {
63 fprintf(stderr, "rb_tree_check_failed after insert!\n");
69 fprintf(stderr, "incorrect N (%d) in tree (vs. %d)\n", t.N, N);
73 for (i = 0; i < N; ++i) {
75 if (!rb_tree_find(&t, &kd)) {
76 fprintf(stderr, "rb_tree_find lost %d!\n", k[i]);
82 for (i = 0; i < N; ++i) {
84 fprintf(stderr, "not enough successors %d\n!", i);
87 printf("%d: %g\n", i, n->k[0]);
91 fprintf(stderr, "too many successors!\n");
96 for (i = 0; i < N; ++i) {
98 fprintf(stderr, "not enough predecessors %d\n!", i);
101 printf("%d: %g\n", i, n->k[0]);
105 fprintf(stderr, "too many predecessors!\n");
109 for (M = N; M > 0; --M) {
110 int knew = rand() % N; /* random new key */
111 j = rand() % M; /* random original key to replace */
112 for (i = 0; i < N; ++i)
118 if (!(n = rb_tree_find(&t, &kd))) {
119 fprintf(stderr, "rb_tree_find lost %d!\n", k[i]);
123 if (!rb_tree_resort(&t, n)) {
124 fprintf(stderr, "error in rb_tree_resort\n");
127 if (!rb_tree_check(&t)) {
128 fprintf(stderr, "rb_tree_check_failed after change %d!\n",
136 fprintf(stderr, "incorrect N (%d) in tree (vs. %d)\n", t.N, N);
140 for (i = 0; i < N; ++i)
141 k[i] = -1 - k[i]; /* undo negation above */
143 for (i = 0; i < N; ++i) {
145 kd = 0.01 * (rand() % (N * 150) - N*25);
146 le = rb_tree_find_le(&t, &kd);
147 gt = rb_tree_find_gt(&t, &kd);
149 double lek = le ? le->k[0] : -HUGE_VAL;
150 double gtk = gt ? gt->k[0] : +HUGE_VAL;
151 printf("%g <= %g < %g\n", lek, kd, gtk);
154 fprintf(stderr, "found invalid le %g for %g\n", lek, kd);
158 fprintf(stderr, "gt is not first node for k=%g\n", kd);
166 succ = rb_tree_succ(n);
167 } while (succ && succ->k[0] <= kd);
170 "rb_tree_find_le gave wrong result for k=%g\n",kd);
175 "rb_tree_find_gt gave wrong result for k=%g\n",kd);
181 for (M = N; M > 0; --M) {
183 for (i = 0; i < N; ++i)
189 if (!(n = rb_tree_find(&t, &kd))) {
190 fprintf(stderr, "rb_tree_find lost %d!\n", k[i]);
193 n = rb_tree_remove(&t, n);
196 if (!rb_tree_check(&t)) {
197 fprintf(stderr, "rb_tree_check_failed after remove!\n");
204 fprintf(stderr, "nonzero N (%d) in tree at end\n", t.N);
211 printf("SUCCESS.\n");