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++)
146 /* Remove an element a from the AVL tree t
147 * returns -1 if the depth of the tree has shrunk
148 * Warning: if the element is not present in the tree,
149 * returns 0 as if it had been removed succesfully.
151 int avl_remove(avl_tree* t, avl* a) {
154 return avl_removeroot(t);
155 b = t->compar(t->root, a);
157 /* remove from the left subtree */
159 avl_tree left_subtree;
160 if ((left_subtree.root = t->root->left)) {
161 left_subtree.compar = t->compar;
162 ch = avl_remove(&left_subtree, a);
163 t->root->left = left_subtree.root;
165 switch (t->root->balance++) {
171 switch (t->root->right->balance) {
174 t->root->balance = -1;
175 t->root->left->balance = 1;
179 t->root->balance = 0;
180 t->root->left->balance = 0;
183 avl_swr(&(t->root->right));
191 /* remove from the right subtree */
193 avl_tree right_subtree;
194 if ((right_subtree.root = t->root->right)) {
195 right_subtree.compar = t->compar;
196 ch = avl_remove(&right_subtree, a);
197 t->root->right = right_subtree.root;
199 switch (t->root->balance--) {
205 switch (t->root->left->balance) {
208 t->root->balance = 1;
209 t->root->right->balance = -1;
213 t->root->balance = 0;
214 t->root->right->balance = 0;
217 avl_swl(&(t->root->left));
227 /* Remove the root of the AVL tree t
228 * Warning: dumps core if t is empty
230 int avl_removeroot(avl_tree* t) {
233 if (!t->root->left) {
234 if (!t->root->right) {
238 t->root = t->root->right;
241 if (!t->root->right) {
242 t->root = t->root->left;
245 if (t->root->balance < 0) {
246 /* remove from the left subtree */
251 /* remove from the right subtree */
256 ch = avl_remove(t, a);
257 a->left = t->root->left;
258 a->right = t->root->right;
259 a->balance = t->root->balance;
266 /* Iterate through elements in t from a range between a and b (inclusive)
267 * for each element calls iter(a) until it returns 0
268 * returns the last value returned by iterator or 0 if there were no calls
269 * Warning: a<=b must hold
271 int avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl* a), avl** ret) {
275 x = t->compar(t->root, a);
278 x = t->compar(t->root, b);
284 /* search in the left subtree */
285 avl_tree left_subtree;
286 if ((left_subtree.root = t->root->left)) {
287 left_subtree.compar = t->compar;
288 if (!(c = avl_range(&left_subtree, a, b, iter, ret)))
294 if (!(c = iter(t->root))) {
301 /* search in the right subtree */
302 avl_tree right_subtree;
303 if ((right_subtree.root = t->root->right)) {
304 right_subtree.compar = t->compar;
305 if (!(c = avl_range(&right_subtree, a, b, iter, ret)))
313 /* Iterate through elements in t equal to a
314 * for each element calls iter(a) until it returns 0
315 * returns the last value returned by iterator or 0 if there were no calls
317 int avl_search(avl_tree* t, avl* a, int (*iter)(avl* a), avl** ret) {
318 return avl_range(t, a, a, iter, ret);