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
22 int _avl_removeroot(avl_tree* t);
25 * Warning: no balance maintainance
27 void avl_swl(avl** root) {
36 * Warning: no balance maintainance
38 void avl_swr(avl** root) {
46 /* Balance maintainance after especially nasty swings
48 void avl_nasty(avl* root) {
49 switch (root->balance) {
51 root->left->balance = 0;
52 root->right->balance = 1;
55 root->left->balance = -1;
56 root->right->balance = 0;
59 root->left->balance = 0;
60 root->right->balance = 0;
67 /* Insert element a into the AVL tree t
68 * returns 1 if the depth of the tree has grown
69 * Warning: do not insert elements already present
71 int _avl_insert(avl_tree* t, avl* a) {
76 /* insert into an empty tree */
82 if (t->compar(t->root, a) > 0) {
83 /* insert into the left subtree */
85 avl_tree left_subtree;
86 left_subtree.root = t->root->left;
87 left_subtree.compar = t->compar;
88 if (_avl_insert(&left_subtree, a)) {
89 switch (t->root->balance--) {
95 if (t->root->left->balance < 0) {
98 t->root->right->balance = 0;
100 avl_swl(&(t->root->left));
105 t->root->left = left_subtree.root;
109 if (t->root->balance--)
114 /* insert into the right subtree */
115 if (t->root->right) {
116 avl_tree right_subtree;
117 right_subtree.root = t->root->right;
118 right_subtree.compar = t->compar;
119 if (_avl_insert(&right_subtree, a)) {
120 switch (t->root->balance++) {
126 if (t->root->right->balance > 0) {
128 t->root->balance = 0;
129 t->root->left->balance = 0;
131 avl_swr(&(t->root->right));
136 t->root->right = right_subtree.root;
140 if (t->root->balance++)
146 int avl_insert(avl_tree* t, avl* a) {
147 #ifdef AVL_LOCK_WITH_MUTEX
148 pthread_mutex_lock(&t->mutex);
150 pthread_rwlock_wrlock(&t->rwlock);
153 int ret = _avl_insert(t, a);
155 #ifdef AVL_LOCK_WITH_MUTEX
156 pthread_mutex_unlock(&t->mutex);
158 pthread_rwlock_unlock(&t->rwlock);
163 /* Remove an element a from the AVL tree t
164 * returns -1 if the depth of the tree has shrunk
165 * Warning: if the element is not present in the tree,
166 * returns 0 as if it had been removed succesfully.
168 int _avl_remove(avl_tree* t, avl* a) {
171 return _avl_removeroot(t);
172 b = t->compar(t->root, a);
174 /* remove from the left subtree */
176 avl_tree left_subtree;
177 if ((left_subtree.root = t->root->left)) {
178 left_subtree.compar = t->compar;
179 ch = _avl_remove(&left_subtree, a);
180 t->root->left = left_subtree.root;
182 switch (t->root->balance++) {
188 switch (t->root->right->balance) {
191 t->root->balance = -1;
192 t->root->left->balance = 1;
196 t->root->balance = 0;
197 t->root->left->balance = 0;
200 avl_swr(&(t->root->right));
208 /* remove from the right subtree */
210 avl_tree right_subtree;
211 if ((right_subtree.root = t->root->right)) {
212 right_subtree.compar = t->compar;
213 ch = _avl_remove(&right_subtree, a);
214 t->root->right = right_subtree.root;
216 switch (t->root->balance--) {
222 switch (t->root->left->balance) {
225 t->root->balance = 1;
226 t->root->right->balance = -1;
230 t->root->balance = 0;
231 t->root->right->balance = 0;
234 avl_swl(&(t->root->left));
244 int avl_remove(avl_tree* t, avl* a) {
245 #ifdef AVL_LOCK_WITH_MUTEX
246 pthread_mutex_lock(&t->mutex);
248 pthread_rwlock_wrlock(&t->rwlock);
251 int ret = _avl_remove(t, a);
253 #ifdef AVL_LOCK_WITH_MUTEX
254 pthread_mutex_unlock(&t->mutex);
256 pthread_rwlock_unlock(&t->rwlock);
261 /* Remove the root of the AVL tree t
262 * Warning: dumps core if t is empty
264 int _avl_removeroot(avl_tree* t) {
267 if (!t->root->left) {
268 if (!t->root->right) {
272 t->root = t->root->right;
275 if (!t->root->right) {
276 t->root = t->root->left;
279 if (t->root->balance < 0) {
280 /* remove from the left subtree */
285 /* remove from the right subtree */
290 ch = _avl_remove(t, a);
291 a->left = t->root->left;
292 a->right = t->root->right;
293 a->balance = t->root->balance;
300 int avl_removeroot(avl_tree* t) {
301 #ifdef AVL_LOCK_WITH_MUTEX
302 pthread_mutex_lock(&t->mutex);
304 pthread_rwlock_wrlock(&t->rwlock);
307 int ret = _avl_removeroot(t);
309 #ifdef AVL_LOCK_WITH_MUTEX
310 pthread_mutex_unlock(&t->mutex);
312 pthread_rwlock_unlock(&t->rwlock);
317 /* Iterate through elements in t from a range between a and b (inclusive)
318 * for each element calls iter(a) until it returns 0
319 * returns the last value returned by iterator or 0 if there were no calls
320 * Warning: a<=b must hold
322 int _avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret) {
326 x = t->compar(t->root, a);
329 x = t->compar(t->root, b);
335 /* search in the left subtree */
336 avl_tree left_subtree;
337 if ((left_subtree.root = t->root->left)) {
338 left_subtree.compar = t->compar;
339 if (!(c = _avl_range(&left_subtree, a, b, iter, ret)))
345 if (!(c = iter(t->root))) {
352 /* search in the right subtree */
353 avl_tree right_subtree;
354 if ((right_subtree.root = t->root->right)) {
355 right_subtree.compar = t->compar;
356 if (!(c = _avl_range(&right_subtree, a, b, iter, ret)))
364 int avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret) {
365 #ifdef AVL_LOCK_WITH_MUTEX
366 pthread_mutex_lock(&t->mutex);
368 pthread_rwlock_wrlock(&t->rwlock);
371 int ret2 = _avl_range(t, a, b, iter, ret);
373 #ifdef AVL_LOCK_WITH_MUTEX
374 pthread_mutex_unlock(&t->mutex);
376 pthread_rwlock_unlock(&t->rwlock);
382 /* Iterate through elements in t equal to a
383 * for each element calls iter(a) until it returns 0
384 * returns the last value returned by iterator or 0 if there were no calls
386 int avl_search(avl_tree* t, avl* a, int (*iter)(avl* a), avl** ret) {
387 return avl_range(t, a, a, iter, ret);
390 void avl_init(avl_tree* t, int (*compar)(void* a, void* b)) {
393 #ifdef AVL_LOCK_WITH_MUTEX
394 pthread_mutex_init(&t->mutex, NULL);
396 pthread_rwlock_init(&t->rwlock, NULL);