rb.c

Tue, 16 Mar 2004 21:35:13 +0100

author
tuomov
date
Tue, 16 Mar 2004 21:35:13 +0100
changeset 70
e866dc825481
parent 68
7a97a1769840
permissions
-rw-r--r--

trunk: changeset 1408
Changed include directives to reflect change in locations of headers.

65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
1 /*
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
2 Generic C code for red-black trees.
68
7a97a1769840 trunk: changeset 1373
tuomov
parents: 67
diff changeset
3 Copyright (C) 2000 James S. Plank,
7a97a1769840 trunk: changeset 1373
tuomov
parents: 67
diff changeset
4 2004 Tuomo Valkonen.
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
5
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
6 This library is free software; you can redistribute it and/or
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
7 modify it under the terms of the GNU Lesser General Public
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
8 License as published by the Free Software Foundation; either
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
9 version 2.1 of the License, or (at your option) any later version.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
10
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
11 This library is distributed in the hope that it will be useful,
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
14 Lesser General Public License for more details.
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
15
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
16 You should have received a copy of the GNU Lesser General Public
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
17 License along with this library; if not, write to the Free Software
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
19 */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
20 /* Revision 1.2. Jim Plank */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
21
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
22 /* Original code by Jim Plank (plank@cs.utk.edu) */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
23 /* modified for THINK C 6.0 for Macintosh by Chris Bartley */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
24
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
25 #include <string.h>
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
26 #include <stdio.h>
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
27 #include <stdlib.h>
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
28 #include <ctype.h>
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
29 #include "rb.h"
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
30
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
31 static void mk_new_int(Rb_node l, Rb_node r, Rb_node p, int il);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
32 static Rb_node lprev(Rb_node n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
33 static Rb_node rprev(Rb_node n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
34 static void recolor(Rb_node n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
35 static void single_rotate(Rb_node y, int l);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
36 static void rb_print_tree(Rb_node t, int level);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
37 static void rb_iprint_tree(Rb_node t, int level);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
38
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
39 /* Gcc complains if non-char* pointer is passed to printf %p */
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
40 #define DONT_COMPLAIN (char*)
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
41
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
42 #define isred(n) (n->s.red)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
43 #define isblack(n) (!isred(n))
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
44 #define isleft(n) (n->s.left)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
45 #define isright(n) (!isleft(n))
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
46 #define isint(n) (n->s.internal)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
47 #define isext(n) (!isint(n))
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
48 #define ishead(n) (n->s.head)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
49 #define isroot(n) (n->s.root)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
50 #define setred(n) n->s.red = 1
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
51 #define setblack(n) n->s.red = 0
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
52 #define setleft(n) n->s.left = 1
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
53 #define setright(n) n->s.left = 0
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
54 #define sethead(n) n->s.head = 1
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
55 #define setroot(n) n->s.root = 1
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
56 #define setint(n) n->s.internal = 1
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
57 #define setext(n) n->s.internal = 0
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
58 #define setnormal(n) { n->s.root = 0; n ->s.head = 0; }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
59 #define sibling(n) ((isleft(n)) ? n->p.parent->c.child.right \
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
60 : n->p.parent->c.child.left)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
61
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
62 static void insert(Rb_node item, Rb_node list) /* Inserts to the end of a list */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
63 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
64 Rb_node last_node;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
66 last_node = list->c.list.blink;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
67
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
68 list->c.list.blink = item;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
69 last_node->c.list.flink = item;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
70 item->c.list.blink = last_node;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
71 item->c.list.flink = list;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
72 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
73
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
74 static void delete_item(Rb_node item) /* Deletes an arbitrary iterm */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
75 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
76 item->c.list.flink->c.list.blink = item->c.list.blink;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
77 item->c.list.blink->c.list.flink = item->c.list.flink;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
78 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
79
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
80 #define mk_new_ext(new, kkkey, vvval) {\
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
81 new = (Rb_node) malloc(sizeof(struct rb_node));\
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
82 if(new==NULL) return NULL;\
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
83 new->v.val = vvval;\
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
84 new->k.key = kkkey;\
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
85 setext(new);\
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
86 setblack(new);\
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
87 setnormal(new);\
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
88 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
89
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
90 static void mk_new_int(Rb_node l, Rb_node r, Rb_node p, int il)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
91 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
92 Rb_node newnode;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
93
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
94 newnode = (Rb_node) malloc(sizeof(struct rb_node));
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
95 setint(newnode);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
96 setred(newnode);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
97 setnormal(newnode);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
98 newnode->c.child.left = l;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
99 newnode->c.child.right = r;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
100 newnode->p.parent = p;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
101 newnode->k.lext = l;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
102 newnode->v.rext = r;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
103 l->p.parent = newnode;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
104 r->p.parent = newnode;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
105 setleft(l);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
106 setright(r);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
107 if (ishead(p)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
108 p->p.root = newnode;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
109 setroot(newnode);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
110 } else if (il) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
111 setleft(newnode);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
112 p->c.child.left = newnode;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
113 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
114 setright(newnode);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
115 p->c.child.right = newnode;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
116 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
117 recolor(newnode);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
118 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
119
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
120
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
121 Rb_node lprev(Rb_node n)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
122 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
123 if (ishead(n)) return n;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
124 while (!isroot(n)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
125 if (isright(n)) return n->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
126 n = n->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
127 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
128 return n->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
129 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
130
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
131 Rb_node rprev(Rb_node n)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
132 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
133 if (ishead(n)) return n;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
134 while (!isroot(n)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
135 if (isleft(n)) return n->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
136 n = n->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
137 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
138 return n->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
139 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
140
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
141 Rb_node make_rb()
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
142 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
143 Rb_node head;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
144
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
145 head = (Rb_node) malloc (sizeof(struct rb_node));
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
146 if(head!=NULL){
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
147 head->c.list.flink = head;
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
148 head->c.list.blink = head;
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
149 head->p.root = head;
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
150 head->k.key = "";
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
151 sethead(head);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
152 }
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
153 return head;
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
154 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
155
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
156 Rb_node rb_find_ikey_n(Rb_node n, int ikey, int *fnd)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
157 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
158 *fnd = 0;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
159 if (!ishead(n)) {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
160 fprintf(stderr, "rb_find_ikey_n called on non-head %p\n",
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
161 DONT_COMPLAIN n);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
162 exit(1);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
163 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
164 if (n->p.root == n) return n;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
165 if (ikey == n->c.list.blink->k.ikey) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
166 *fnd = 1;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
167 return n->c.list.blink;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
168 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
169 if (ikey > n->c.list.blink->k.ikey) return n;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
170 else n = n->p.root;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
171 while (1) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
172 if (isext(n)) return n;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
173 if (ikey == n->k.lext->k.ikey) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
174 *fnd = 1;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
175 return n->k.lext;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
176 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
177 n = (ikey < n->k.lext->k.ikey) ? n->c.child.left : n->c.child.right;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
178 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
179 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
180
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
181 Rb_node rb_find_ikey(Rb_node n, int ikey)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
182 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
183 int fnd;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
184 return rb_find_ikey_n(n, ikey, &fnd);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
185 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
186
67
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
187 Rb_node rb_find_gkey_n(Rb_node n, const void *key, Rb_compfn *fxn, int *fnd)
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
188 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
189 int cmp;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
190
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
191 *fnd = 0;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
192 if (!ishead(n)) {
67
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
193 fprintf(stderr, "rb_find_gkey_n called on non-head %p\n",
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
194 DONT_COMPLAIN n);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
195 exit(1);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
196 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
197 if (n->p.root == n) return n;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
198 cmp = (*fxn)(key, n->c.list.blink->k.key);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
199 if (cmp == 0) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
200 *fnd = 1;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
201 return n->c.list.blink;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
202 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
203 if (cmp > 0) return n;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
204 else n = n->p.root;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
205 while (1) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
206 if (isext(n)) return n;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
207 cmp = (*fxn)(key, n->k.lext->k.key);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
208 if (cmp == 0) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
209 *fnd = 1;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
210 return n->k.lext;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
211 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
212 if (cmp < 0) n = n->c.child.left ; else n = n->c.child.right;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
213 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
214 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
215
67
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
216 Rb_node rb_find_gkey(Rb_node n, const void *key, Rb_compfn *fxn)
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
217 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
218 int fnd;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
219 return rb_find_gkey_n(n, key, fxn, &fnd);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
220 }
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
221
67
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
222 Rb_node rb_find_key_n(Rb_node n, const char *key, int *fnd)
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
223 {
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
224 return rb_find_gkey_n(n, key, (Rb_compfn*)strcmp, fnd);
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
225 }
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
226
67
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
227 Rb_node rb_find_key(Rb_node n, const char *key)
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
228 {
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
229 int fnd;
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
230 return rb_find_gkey_n(n, key, (Rb_compfn*)strcmp, &fnd);
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
231 }
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
232
67
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
233 static int ptrcmp(const void *a, const void *b)
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
234 {
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
235 return (a<b ? -1 : ((a==b) ? 0 : 1));
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
236 }
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
237
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
238 Rb_node rb_find_pkey_n(Rb_node n, const void *key, int *fnd)
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
239 {
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
240 return rb_find_gkey_n(n, key, ptrcmp, fnd);
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
241 }
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
242
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
243 Rb_node rb_find_pkey(Rb_node n, const void *key)
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
244 {
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
245 int fnd;
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
246 return rb_find_gkey_n(n, key, ptrcmp, &fnd);
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
247 }
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
248
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
249 Rb_node rb_insert_b(Rb_node n, const void *key, void *val)
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
250 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
251 Rb_node newleft, newright, newnode, list, p;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
252
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
253 if (ishead(n)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
254 if (n->p.root == n) { /* Tree is empty */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
255 mk_new_ext(newnode, key, val);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
256 insert(newnode, n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
257 n->p.root = newnode;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
258 newnode->p.parent = n;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
259 setroot(newnode);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
260 return newnode;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
261 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
262 mk_new_ext(newright, key, val);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
263 insert(newright, n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
264 newleft = newright->c.list.blink;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
265 setnormal(newleft);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
266 mk_new_int(newleft, newright, newleft->p.parent, isleft(newleft));
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
267 p = rprev(newright);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
268 if (!ishead(p)) p->k.lext = newright;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
269 return newright;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
270 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
271 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
272 mk_new_ext(newleft, key, val);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
273 insert(newleft, n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
274 setnormal(n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
275 mk_new_int(newleft, n, n->p.parent, isleft(n));
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
276 p = lprev(newleft);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
277 if (!ishead(p)) p->v.rext = newleft;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
278 return newleft;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
279 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
280 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
281
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
282 static void recolor(Rb_node n)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
283 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
284 Rb_node p, gp, s;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
285 int done = 0;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
286
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
287 while(!done) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
288 if (isroot(n)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
289 setblack(n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
290 return;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
291 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
292
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
293 p = n->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
294
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
295 if (isblack(p)) return;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
296
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
297 if (isroot(p)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
298 setblack(p);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
299 return;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
300 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
301
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
302 gp = p->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
303 s = sibling(p);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
304 if (isred(s)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
305 setblack(p);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
306 setred(gp);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
307 setblack(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
308 n = gp;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
309 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
310 done = 1;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
311 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
312 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
313 /* p's sibling is black, p is red, gp is black */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
314
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
315 if ((isleft(n) == 0) == (isleft(p) == 0)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
316 single_rotate(gp, isleft(n));
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
317 setblack(p);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
318 setred(gp);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
319 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
320 single_rotate(p, isleft(n));
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
321 single_rotate(gp, isleft(n));
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
322 setblack(n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
323 setred(gp);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
324 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
325 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
326
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
327 static void single_rotate(Rb_node y, int l)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
328 {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
329 int rl=0, ir=0;
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
330 Rb_node x=NULL, yp=NULL;
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
331 void *tmp=NULL;
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
332
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
333 ir = isroot(y);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
334 yp = y->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
335 if (!ir) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
336 rl = isleft(y);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
337 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
338
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
339 if (l) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
340 x = y->c.child.left;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
341 y->c.child.left = x->c.child.right;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
342 setleft(y->c.child.left);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
343 y->c.child.left->p.parent = y;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
344 x->c.child.right = y;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
345 setright(y);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
346 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
347 x = y->c.child.right;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
348 y->c.child.right = x->c.child.left;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
349 setright(y->c.child.right);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
350 y->c.child.right->p.parent = y;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
351 x->c.child.left = y;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
352 setleft(y);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
353 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
354
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
355 x->p.parent = yp;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
356 y->p.parent = x;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
357 if (ir) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
358 yp->p.root = x;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
359 setnormal(y);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
360 setroot(x);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
361 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
362 if (rl) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
363 yp->c.child.left = x;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
364 setleft(x);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
365 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
366 yp->c.child.right = x;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
367 setright(x);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
368 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
369 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
370 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
371
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
372 void rb_delete_node(Rb_node n)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
373 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
374 Rb_node s, p, gp;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
375 char ir;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
376
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
377 if (isint(n)) {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
378 fprintf(stderr, "Cannot delete an internal node: %p\n", DONT_COMPLAIN n);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
379 exit(1);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
380 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
381 if (ishead(n)) {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
382 fprintf(stderr, "Cannot delete the head of an rb_tree: %p\n", DONT_COMPLAIN n);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
383 exit(1);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
384 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
385 delete_item(n); /* Delete it from the list */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
386 p = n->p.parent; /* The only node */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
387 if (isroot(n)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
388 p->p.root = p;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
389 free(n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
390 return;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
391 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
392 s = sibling(n); /* The only node after deletion */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
393 if (isroot(p)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
394 s->p.parent = p->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
395 s->p.parent->p.root = s;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
396 setroot(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
397 free(p);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
398 free(n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
399 return;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
400 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
401 gp = p->p.parent; /* Set parent to sibling */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
402 s->p.parent = gp;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
403 if (isleft(p)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
404 gp->c.child.left = s;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
405 setleft(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
406 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
407 gp->c.child.right = s;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
408 setright(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
409 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
410 ir = isred(p);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
411 free(p);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
412 free(n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
413
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
414 if (isext(s)) { /* Update proper rext and lext values */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
415 p = lprev(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
416 if (!ishead(p)) p->v.rext = s;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
417 p = rprev(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
418 if (!ishead(p)) p->k.lext = s;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
419 } else if (isblack(s)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
420 fprintf(stderr, "DELETION PROB -- sib is black, internal\n");
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
421 exit(1);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
422 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
423 p = lprev(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
424 if (!ishead(p)) p->v.rext = s->c.child.left;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
425 p = rprev(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
426 if (!ishead(p)) p->k.lext = s->c.child.right;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
427 setblack(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
428 return;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
429 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
430
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
431 if (ir) return;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
432
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
433 /* Recolor */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
434
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
435 n = s;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
436 p = n->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
437 s = sibling(n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
438 while(isblack(p) && isblack(s) && isint(s) &&
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
439 isblack(s->c.child.left) && isblack(s->c.child.right)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
440 setred(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
441 n = p;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
442 if (isroot(n)) return;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
443 p = n->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
444 s = sibling(n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
445 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
446
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
447 if (isblack(p) && isred(s)) { /* Rotation 2.3b */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
448 single_rotate(p, isright(n));
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
449 setred(p);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
450 setblack(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
451 s = sibling(n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
452 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
453
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
454 { Rb_node x, z; char il;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
455
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
456 if (isext(s)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
457 fprintf(stderr, "DELETION ERROR: sibling not internal\n");
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
458 exit(1);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
459 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
460
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
461 il = isleft(n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
462 x = il ? s->c.child.left : s->c.child.right ;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
463 z = sibling(x);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
464
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
465 if (isred(z)) { /* Rotation 2.3f */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
466 single_rotate(p, !il);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
467 setblack(z);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
468 if (isred(p)) setred(s); else setblack(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
469 setblack(p);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
470 } else if (isblack(x)) { /* Recoloring only (2.3c) */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
471 if (isred(s) || isblack(p)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
472 fprintf(stderr, "DELETION ERROR: 2.3c not quite right\n");
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
473 exit(1);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
474 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
475 setblack(p);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
476 setred(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
477 return;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
478 } else if (isred(p)) { /* 2.3d */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
479 single_rotate(s, il);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
480 single_rotate(p, !il);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
481 setblack(x);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
482 setred(s);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
483 return;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
484 } else { /* 2.3e */
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
485 single_rotate(s, il);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
486 single_rotate(p, !il);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
487 setblack(x);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
488 return;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
489 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
490 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
491 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
492
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
493
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
494 void rb_print_tree(Rb_node t, int level)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
495 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
496 int i;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
497 if (ishead(t) && t->p.parent == t) {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
498 printf("tree %p is empty\n", DONT_COMPLAIN t);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
499 } else if (ishead(t)) {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
500 printf("Head: %p. Root = %p\n", DONT_COMPLAIN t, DONT_COMPLAIN t->p.root);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
501 rb_print_tree(t->p.root, 0);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
502 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
503 if (isext(t)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
504 for (i = 0; i < level; i++) putchar(' ');
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
505 printf("Ext node %p: %c,%c: p=%p, k=%s\n",
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
506 DONT_COMPLAIN t, isred(t)?'R':'B', isleft(t)?'l':'r',
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
507 DONT_COMPLAIN t->p.parent, DONT_COMPLAIN t->k.key);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
508 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
509 rb_print_tree(t->c.child.left, level+2);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
510 rb_print_tree(t->c.child.right, level+2);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
511 for (i = 0; i < level; i++) putchar(' ');
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
512 printf("Int node %p: %c,%c: l=%p, r=%p, p=%p, lr=(%s,%s)\n",
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
513 DONT_COMPLAIN t, isred(t)?'R':'B', isleft(t)?'l':'r',
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
514 DONT_COMPLAIN t->c.child.left, DONT_COMPLAIN t->c.child.right,
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
515 DONT_COMPLAIN t->p.parent, DONT_COMPLAIN t->k.lext->k.key,
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
516 DONT_COMPLAIN t->v.rext->k.key);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
517 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
518 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
519 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
520
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
521 void rb_iprint_tree(Rb_node t, int level)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
522 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
523 int i;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
524 if (ishead(t) && t->p.parent == t) {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
525 printf("tree %p is empty\n", DONT_COMPLAIN t);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
526 } else if (ishead(t)) {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
527 printf("Head: %p. Root = %p, < = %p, > = %p\n",
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
528 DONT_COMPLAIN t, DONT_COMPLAIN t->p.root,
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
529 DONT_COMPLAIN t->c.list.blink,
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
530 DONT_COMPLAIN t->c.list.flink);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
531 rb_iprint_tree(t->p.root, 0);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
532 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
533 if (isext(t)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
534 for (i = 0; i < level; i++) putchar(' ');
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
535 printf("Ext node %p: %c,%c: p=%p, <=%p, >=%p k=%d\n",
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
536 DONT_COMPLAIN t, isred(t)?'R':'B', isleft(t)?'l':'r',
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
537 DONT_COMPLAIN t->p.parent, DONT_COMPLAIN t->c.list.blink,
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
538 DONT_COMPLAIN t->c.list.flink, t->k.ikey);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
539 } else {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
540 rb_iprint_tree(t->c.child.left, level+2);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
541 rb_iprint_tree(t->c.child.right, level+2);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
542 for (i = 0; i < level; i++) putchar(' ');
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
543 printf("Int node %p: %c,%c: l=%p, r=%p, p=%p, lr=(%d,%d)\n",
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
544 DONT_COMPLAIN t, isred(t)?'R':'B', isleft(t)?'l':'r',
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
545 DONT_COMPLAIN t->c.child.left, DONT_COMPLAIN t->c.child.right,
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
546 DONT_COMPLAIN t->p.parent, t->k.lext->k.ikey, t->v.rext->k.ikey);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
547 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
548 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
549 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
550
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
551 int rb_nblack(Rb_node n)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
552 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
553 int nb;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
554 if (ishead(n) || isint(n)) {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
555 fprintf(stderr, "ERROR: rb_nblack called on a non-external node %p\n",
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
556 DONT_COMPLAIN n);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
557 exit(1);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
558 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
559 nb = 0;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
560 while(!ishead(n)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
561 if (isblack(n)) nb++;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
562 n = n->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
563 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
564 return nb;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
565 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
566
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
567 int rb_plength(Rb_node n)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
568 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
569 int pl;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
570 if (ishead(n) || isint(n)) {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
571 fprintf(stderr, "ERROR: rb_plength called on a non-external node %p\n",
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
572 DONT_COMPLAIN n);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
573 exit(1);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
574 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
575 pl = 0;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
576 while(!ishead(n)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
577 pl++;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
578 n = n->p.parent;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
579 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
580 return pl;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
581 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
582
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
583 void rb_free_tree(Rb_node n)
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
584 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
585 if (!ishead(n)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
586 fprintf(stderr, "ERROR: Rb_free_tree called on a non-head node\n");
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
587 exit(1);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
588 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
589
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
590 while(rb_first(n) != rb_nil(n)) {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
591 rb_delete_node(rb_first(n));
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
592 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
593 free(n);
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
594 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
595
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
596 void *rb_val(Rb_node n)
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
597 {
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
598 return n->v.val;
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
599 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
600
67
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
601 Rb_node rb_insert_a(Rb_node nd, const void *key, void *val)
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
602 {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
603 return rb_insert_b(nd->c.list.flink, key, val);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
604 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
605
67
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
606 Rb_node rb_insert(Rb_node tree, const char *key, void *val)
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
607 {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
608 return rb_insert_b(rb_find_key(tree, key), key, val);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
609 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
610
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
611 Rb_node rb_inserti(Rb_node tree, int ikey, void *val)
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
612 {
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
613 return rb_insert_b(rb_find_ikey(tree, ikey), (void *) ikey, val);
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
614 }
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
615
67
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
616 Rb_node rb_insertg(Rb_node tree, const void *key, void *val, Rb_compfn *func)
66
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
617 {
42085c134e29 trunk: changeset 1369
tuomov
parents: 65
diff changeset
618 return rb_insert_b(rb_find_gkey(tree, key, func), key, val);
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
619 }
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
620
67
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
621 Rb_node rb_insertp(Rb_node tree, const void *key, void *val)
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
622 {
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
623 return rb_insertg(tree, key, val, ptrcmp);
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
624 }
65
58e382ae97cd trunk: changeset 1368
tuomov
parents:
diff changeset
625
67
b53529762874 trunk: changeset 1370
tuomov
parents: 66
diff changeset
626

mercurial