2 * ANSI C Library for maintainance of AVL Balanced Trees
5 * G. M. Adelson-Velskij & E. M. Landis
6 * Doklady Akad. Nauk SSSR 146 (1962), 263-266
9 * D. E. Knuth: The Art of Computer Programming Vol.3 (Sorting and Searching)
11 * (C) 2000 Daniel Nagy, Budapest University of Technology and Economics
12 * Released under GNU General Public License (GPL) version 2
24 * Warning: no balance maintainance
26 void avl_swl(avl** root) {
35 * Warning: no balance maintainance
37 void avl_swr(avl** root) {
45 /* Balance maintainance after especially nasty swings
47 void avl_nasty(avl* root) {
48 switch (root->balance) {
50 root->left->balance = 0;
51 root->right->balance = 1;
54 root->left->balance = -1;
55 root->right->balance = 0;
58 root->left->balance = 0;
59 root->right->balance = 0;
66 /* Insert element a into the AVL tree t
67 * returns 1 if the depth of the tree has grown
68 * Warning: do not insert elements already present
70 int _avl_insert(avl_tree* t, avl* a) {
75 /* insert into an empty tree */
81 if (t->compar(t->root, a) > 0) {
82 /* insert into the left subtree */
84 avl_tree left_subtree;
85 left_subtree.root = t->root->left;
86 left_subtree.compar = t->compar;
87 if (_avl_insert(&left_subtree, a)) {
88 switch (t->root->balance--) {
94 if (t->root->left->balance < 0) {
97 t->root->right->balance = 0;
99 avl_swl(&(t->root->left));
104 t->root->left = left_subtree.root;
108 if (t->root->balance--)
113 /* insert into the right subtree */
114 if (t->root->right) {
115 avl_tree right_subtree;
116 right_subtree.root = t->root->right;
117 right_subtree.compar = t->compar;
118 if (_avl_insert(&right_subtree, a)) {
119 switch (t->root->balance++) {
125 if (t->root->right->balance > 0) {
127 t->root->balance = 0;
128 t->root->left->balance = 0;
130 avl_swr(&(t->root->right));
135 t->root->right = right_subtree.root;
139 if (t->root->balance++)
145 int avl_insert(avl_tree* t, avl* a) {
146 pthread_rwlock_wrlock(&t->rwlock);
147 int ret = _avl_insert(t, a);
148 pthread_rwlock_unlock(&t->rwlock);
152 /* Remove an element a from the AVL tree t
153 * returns -1 if the depth of the tree has shrunk
154 * Warning: if the element is not present in the tree,
155 * returns 0 as if it had been removed succesfully.
157 int _avl_remove(avl_tree* t, avl* a) {
160 return _avl_removeroot(t);
161 b = t->compar(t->root, a);
163 /* remove from the left subtree */
165 avl_tree left_subtree;
166 if ((left_subtree.root = t->root->left)) {
167 left_subtree.compar = t->compar;
168 ch = _avl_remove(&left_subtree, a);
169 t->root->left = left_subtree.root;
171 switch (t->root->balance++) {
177 switch (t->root->right->balance) {
180 t->root->balance = -1;
181 t->root->left->balance = 1;
185 t->root->balance = 0;
186 t->root->left->balance = 0;
189 avl_swr(&(t->root->right));
197 /* remove from the right subtree */
199 avl_tree right_subtree;
200 if ((right_subtree.root = t->root->right)) {
201 right_subtree.compar = t->compar;
202 ch = _avl_remove(&right_subtree, a);
203 t->root->right = right_subtree.root;
205 switch (t->root->balance--) {
211 switch (t->root->left->balance) {
214 t->root->balance = 1;
215 t->root->right->balance = -1;
219 t->root->balance = 0;
220 t->root->right->balance = 0;
223 avl_swl(&(t->root->left));
233 int avl_remove(avl_tree* t, avl* a) {
234 pthread_rwlock_wrlock(&t->rwlock);
235 int ret = _avl_remove(t, a);
236 pthread_rwlock_unlock(&t->rwlock);
240 /* Remove the root of the AVL tree t
241 * Warning: dumps core if t is empty
243 int _avl_removeroot(avl_tree* t) {
246 if (!t->root->left) {
247 if (!t->root->right) {
251 t->root = t->root->right;
254 if (!t->root->right) {
255 t->root = t->root->left;
258 if (t->root->balance < 0) {
259 /* remove from the left subtree */
264 /* remove from the right subtree */
269 ch = _avl_remove(t, a);
270 a->left = t->root->left;
271 a->right = t->root->right;
272 a->balance = t->root->balance;
279 int avl_removeroot(avl_tree* t) {
280 pthread_rwlock_wrlock(&t->rwlock);
281 int ret = _avl_removeroot(t);
282 pthread_rwlock_unlock(&t->rwlock);
286 /* Iterate through elements in t from a range between a and b (inclusive)
287 * for each element calls iter(a) until it returns 0
288 * returns the last value returned by iterator or 0 if there were no calls
289 * Warning: a<=b must hold
291 int _avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl* a), avl** ret) {
295 x = t->compar(t->root, a);
298 x = t->compar(t->root, b);
304 /* search in the left subtree */
305 avl_tree left_subtree;
306 if ((left_subtree.root = t->root->left)) {
307 left_subtree.compar = t->compar;
308 if (!(c = _avl_range(&left_subtree, a, b, iter, ret)))
314 if (!(c = iter(t->root))) {
321 /* search in the right subtree */
322 avl_tree right_subtree;
323 if ((right_subtree.root = t->root->right)) {
324 right_subtree.compar = t->compar;
325 if (!(c = _avl_range(&right_subtree, a, b, iter, ret)))
333 int avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl* a), avl** ret) {
334 pthread_rwlock_rdlock(&t->rwlock);
335 int ret2 = _avl_range(t, a, b, iter, ret);
336 pthread_rwlock_unlock(&t->rwlock);
340 /* Iterate through elements in t equal to a
341 * for each element calls iter(a) until it returns 0
342 * returns the last value returned by iterator or 0 if there were no calls
344 int avl_search(avl_tree* t, avl* a, int (*iter)(avl* a), avl** ret) {
345 return avl_range(t, a, a, iter, ret);
348 void avl_init(avl_tree* t, int (*compar)(void* a, void* b)) {
351 pthread_rwlock_init(&t->rwlock, NULL);