35 #define AVLTREE_PRINT_LEVEL_PADDING 4
49 int (*compare)(
const void *key1,
const void *key2);
50 void (*destroy)(
void *data);
62 static void print_tree(
AvlTreeNode node,
int level,
void (*callback)(
const void *data));
63 static void preorder(
AvlTreeNode node,
void (*callback)(
const void *data));
64 static void inorder(
AvlTreeNode node,
void (*callback)(
const void *data));
65 static void postorder(
AvlTreeNode node,
void (*callback)(
const void *data));
71 AvlTree AVLTREEinit(
int (*compare)(
const void *key1,
const void *key2),
void (*destroy)(
void *data))
79 tree->compare = compare;
80 tree->destroy = destroy;
88 destroy_left(tree, NULL);
96 return insert(tree, &tree->root, data, &balanced);
101 return hide(tree, tree->root, data);
106 return lookup(tree, tree->root, data);
126 return node->left == NULL && node->right == NULL;
152 printf(
"\nAVL TREE STATUS: Size(%d nodes)/Height(%d levels)/(XX=hidden) ---\n",
AVLTREEsize(tree),
AVLTREEheight(tree));
158 preorder(tree->root, callback);
163 inorder(tree->root, callback);
168 postorder(tree->root, callback);
178 left = (*node)->left;
183 (*node)->left = left->right;
192 grandchild = left->right;
193 left->right = grandchild->left;
194 grandchild->left = left;
195 (*node)->left = grandchild->right;
196 grandchild->right = *node;
198 switch (grandchild->factor)
225 right = (*node)->right;
230 (*node)->right = right->left;
239 grandchild = right->left;
240 right->left = grandchild->right;
241 grandchild->right = right;
242 (*node)->right = grandchild->left;
243 grandchild->left = *node;
245 switch (grandchild->factor)
277 position = &tree->root;
279 position = &node->left;
282 if (*position != NULL)
284 destroy_left(tree, *position);
285 destroy_right(tree, *position);
287 if (tree->destroy != NULL)
290 tree->destroy((*position)->data);
312 position = &tree->root;
314 position = &node->right;
317 if (*position != NULL)
319 destroy_left(tree, *position);
320 destroy_right(tree, *position);
322 if (tree->destroy != NULL)
325 tree->destroy((*position)->data);
345 return avltree_insleft(tree, *node, data);
350 cmpval = tree->compare(data, (*node)->data);
355 if ((*node)->left == NULL)
357 if (avltree_insleft(tree, *node, data) != 0)
364 if ((retval = insert(tree, &(*node)->left, data, balanced)) != 0)
373 switch ((*node)->factor)
391 if ((*node)->right == NULL)
393 if (avltree_insright(tree, *node, data) != 0)
400 if ((retval = insert(tree, &(*node)->right, data, balanced)) != 0)
409 switch ((*node)->factor)
427 if (!((*node)->hidden))
435 if (tree->destroy != NULL)
438 tree->destroy((*node)->data);
441 (*node)->data = (
void *)data;
464 cmpval = tree->compare(data, node->data);
469 retval = hide(tree, node->left, data);
474 retval = hide(tree, node->right, data);
503 cmpval = tree->compare(*data, node->data);
508 retval = lookup(tree, node->left, data);
513 retval = lookup(tree, node->right, data);
518 if (!(node->hidden) )
534 static void print_tree(
AvlTreeNode node,
int level,
void (*callback)(
const void *data))
567 static void preorder(
AvlTreeNode node,
void (*callback)(
const void *data))
572 callback(node->data);
574 preorder(node->left, callback);
576 preorder(node->right, callback);
581 static void inorder(
AvlTreeNode node,
void (*callback)(
const void *data))
586 inorder(node->left, callback);
588 callback(node->data);
590 inorder(node->right, callback);
595 static void postorder(
AvlTreeNode node,
void (*callback)(
const void *data))
600 postorder(node->left, callback);
602 postorder(node->right, callback);
604 callback(node->data);
614 return maxval(treeheight(node->left, depth+1),
615 treeheight(node->right, depth+1));
629 position = &tree->root;
634 if (node->left != NULL)
637 position = &node->left;
645 new_node->data = (
void *)data;
647 new_node->hidden = 0;
648 new_node->left = NULL;
649 new_node->right = NULL;
650 *position = new_node;
669 position = &tree->root;
674 if (node->right != NULL)
677 position = &node->right;
685 new_node->data = (
void *)data;
687 new_node->hidden = 0;
688 new_node->left = NULL;
689 new_node->right = NULL;
690 *position = new_node;