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
21 * Warning: no balance maintainance
23 void avl_swl(avl** root) {
32 * Warning: no balance maintainance
34 void avl_swr(avl** root) {
42 /* Balance maintainance after especially nasty swings
44 void avl_nasty(avl* root) {
45 switch (root->balance) {
47 root->left->balance = 0;
48 root->right->balance = 1;
51 root->left->balance = -1;
52 root->right->balance = 0;
55 root->left->balance = 0;
56 root->right->balance = 0;
63 /* Insert element a into the AVL tree t
64 * returns 1 if the depth of the tree has grown
65 * Warning: do not insert elements already present
67 int avl_insert(avl_tree* t, avl* a) {
72 /* insert into an empty tree */
78 if (t->compar(t->root, a) > 0) {
79 /* insert into the left subtree */
81 avl_tree left_subtree;
82 left_subtree.root = t->root->left;
83 left_subtree.compar = t->compar;
84 if (avl_insert(&left_subtree, a)) {
85 switch (t->root->balance--) {
91 if (t->root->left->balance < 0) {
94 t->root->right->balance = 0;
96 avl_swl(&(t->root->left));
101 t->root->left = left_subtree.root;
105 if (t->root->balance--)
110 /* insert into the right subtree */
111 if (t->root->right) {
112 avl_tree right_subtree;
113 right_subtree.root = t->root->right;
114 right_subtree.compar = t->compar;
115 if (avl_insert(&right_subtree, a)) {
116 switch (t->root->balance++) {
122 if (t->root->right->balance > 0) {
124 t->root->balance = 0;
125 t->root->left->balance = 0;
127 avl_swr(&(t->root->right));
132 t->root->right = right_subtree.root;
136 if (t->root->balance++)
143 /* Remove an element a from the AVL tree t
144 * returns -1 if the depth of the tree has shrunk
145 * Warning: if the element is not present in the tree,
146 * returns 0 as if it had been removed succesfully.
148 int avl_remove(avl_tree* t, avl* a) {
151 return avl_removeroot(t);
152 b = t->compar(t->root, a);
154 /* remove from the left subtree */
156 avl_tree left_subtree;
157 if ((left_subtree.root = t->root->left)) {
158 left_subtree.compar = t->compar;
159 ch = avl_remove(&left_subtree, a);
160 t->root->left = left_subtree.root;
162 switch (t->root->balance++) {
168 switch (t->root->right->balance) {
171 t->root->balance = -1;
172 t->root->left->balance = 1;
176 t->root->balance = 0;
177 t->root->left->balance = 0;
180 avl_swr(&(t->root->right));
188 /* remove from the right subtree */
190 avl_tree right_subtree;
191 if ((right_subtree.root = t->root->right)) {
192 right_subtree.compar = t->compar;
193 ch = avl_remove(&right_subtree, a);
194 t->root->right = right_subtree.root;
196 switch (t->root->balance--) {
202 switch (t->root->left->balance) {
205 t->root->balance = 1;
206 t->root->right->balance = -1;
210 t->root->balance = 0;
211 t->root->right->balance = 0;
214 avl_swl(&(t->root->left));
224 /* Remove the root of the AVL tree t
225 * Warning: dumps core if t is empty
227 int avl_removeroot(avl_tree* t) {
230 if (!t->root->left) {
231 if (!t->root->right) {
235 t->root = t->root->right;
238 if (!t->root->right) {
239 t->root = t->root->left;
242 if (t->root->balance < 0) {
243 /* remove from the left subtree */
248 /* remove from the right subtree */
253 ch = avl_remove(t, a);
254 a->left = t->root->left;
255 a->right = t->root->right;
256 a->balance = t->root->balance;
263 /* Iterate through elements in t from a range between a and b (inclusive)
264 * for each element calls iter(a) until it returns 0
265 * returns the last value returned by iterator or 0 if there were no calls
266 * Warning: a<=b must hold
268 int avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl* a), avl** ret) {
272 x = t->compar(t->root, a);
275 x = t->compar(t->root, b);
281 /* search in the left subtree */
282 avl_tree left_subtree;
283 if ((left_subtree.root = t->root->left)) {
284 left_subtree.compar = t->compar;
285 if (!(c = avl_range(&left_subtree, a, b, iter, ret)))
291 if (!(c = iter(t->root))) {
298 /* search in the right subtree */
299 avl_tree right_subtree;
300 if ((right_subtree.root = t->root->right)) {
301 right_subtree.compar = t->compar;
302 if (!(c = avl_range(&right_subtree, a, b, iter, ret)))
310 /* Iterate through elements in t equal to a
311 * for each element calls iter(a) until it returns 0
312 * returns the last value returned by iterator or 0 if there were no calls
314 int avl_search(avl_tree* t, avl* a, int (*iter)(avl* a), avl** ret) {
315 return avl_range(t, a, a, iter, ret);