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 pthread_rwlock_wrlock(&t->rwlock);
148 int ret = _avl_insert(t, a);
149 pthread_rwlock_unlock(&t->rwlock);
153 /* Remove an element a from the AVL tree t
154 * returns -1 if the depth of the tree has shrunk
155 * Warning: if the element is not present in the tree,
156 * returns 0 as if it had been removed succesfully.
158 int _avl_remove(avl_tree* t, avl* a) {
161 return _avl_removeroot(t);
162 b = t->compar(t->root, a);
164 /* remove from the left subtree */
166 avl_tree left_subtree;
167 if ((left_subtree.root = t->root->left)) {
168 left_subtree.compar = t->compar;
169 ch = _avl_remove(&left_subtree, a);
170 t->root->left = left_subtree.root;
172 switch (t->root->balance++) {
178 switch (t->root->right->balance) {
181 t->root->balance = -1;
182 t->root->left->balance = 1;
186 t->root->balance = 0;
187 t->root->left->balance = 0;
190 avl_swr(&(t->root->right));
198 /* remove from the right subtree */
200 avl_tree right_subtree;
201 if ((right_subtree.root = t->root->right)) {
202 right_subtree.compar = t->compar;
203 ch = _avl_remove(&right_subtree, a);
204 t->root->right = right_subtree.root;
206 switch (t->root->balance--) {
212 switch (t->root->left->balance) {
215 t->root->balance = 1;
216 t->root->right->balance = -1;
220 t->root->balance = 0;
221 t->root->right->balance = 0;
224 avl_swl(&(t->root->left));
234 int avl_remove(avl_tree* t, avl* a) {
235 pthread_rwlock_wrlock(&t->rwlock);
236 int ret = _avl_remove(t, a);
237 pthread_rwlock_unlock(&t->rwlock);
241 /* Remove the root of the AVL tree t
242 * Warning: dumps core if t is empty
244 int _avl_removeroot(avl_tree* t) {
247 if (!t->root->left) {
248 if (!t->root->right) {
252 t->root = t->root->right;
255 if (!t->root->right) {
256 t->root = t->root->left;
259 if (t->root->balance < 0) {
260 /* remove from the left subtree */
265 /* remove from the right subtree */
270 ch = _avl_remove(t, a);
271 a->left = t->root->left;
272 a->right = t->root->right;
273 a->balance = t->root->balance;
280 int avl_removeroot(avl_tree* t) {
281 pthread_rwlock_wrlock(&t->rwlock);
282 int ret = _avl_removeroot(t);
283 pthread_rwlock_unlock(&t->rwlock);
287 /* Iterate through elements in t from a range between a and b (inclusive)
288 * for each element calls iter(a) until it returns 0
289 * returns the last value returned by iterator or 0 if there were no calls
290 * Warning: a<=b must hold
292 int _avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl* a), avl** ret) {
296 x = t->compar(t->root, a);
299 x = t->compar(t->root, b);
305 /* search in the left subtree */
306 avl_tree left_subtree;
307 if ((left_subtree.root = t->root->left)) {
308 left_subtree.compar = t->compar;
309 if (!(c = _avl_range(&left_subtree, a, b, iter, ret)))
315 if (!(c = iter(t->root))) {
322 /* search in the right subtree */
323 avl_tree right_subtree;
324 if ((right_subtree.root = t->root->right)) {
325 right_subtree.compar = t->compar;
326 if (!(c = _avl_range(&right_subtree, a, b, iter, ret)))
334 int avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl* a), avl** ret) {
335 pthread_rwlock_rdlock(&t->rwlock);
336 int ret2 = _avl_range(t, a, b, iter, ret);
337 pthread_rwlock_unlock(&t->rwlock);
341 /* Iterate through elements in t equal to a
342 * for each element calls iter(a) until it returns 0
343 * returns the last value returned by iterator or 0 if there were no calls
345 int avl_search(avl_tree* t, avl* a, int (*iter)(avl* a), avl** ret) {
346 return avl_range(t, a, a, iter, ret);
349 void avl_init(avl_tree* t, int (*compar)(void* a, void* b)) {
352 pthread_rwlock_init(&t->rwlock, NULL);