AVL Tree
Download: avl.c
Author: paulie
License: n/a
Description:
- Written in C for UNIX based systems
- Supports insertion, deletion, search and print
Download: avl.c
Author: paulie
License: n/a
Description:
- Written in C for UNIX based systems
- Supports insertion, deletion, search and print
/*
* AVL tree implementation by Paul Johnson
* http://en.wikipedia.org/wiki/AVL_tree
*
* paulie@pauliesworld.org
* http://www.pauliesworld.org
*
*/
#include <stdio.h>
#include <stdlib.h>
struct avl_node {
/*
* Each AVL node has a depth and height variable. Height
* calculates the maximum descendant length of a node's subtree.
* Depth calculates a node's position relative to the root of the
* entire AVL tree. Depth is an expensive variable and is used
* only to print out the tree conveniently. If you use this code,
* I recommend commenting out any thing related to depth
* calculation.
*/
int data;
int depth;
int height;
struct avl_node* left;
struct avl_node* right;
};
int
avl_tree_node_count(struct avl_node* root)
{
if(root == NULL) {
return 0;
}
return(1+avl_tree_node_count(root->left)
+avl_tree_node_count(root->right));
}
int
height(struct avl_node* root)
{
if(root == NULL) {
return 0;
} else {
return root->height;
}
}
int
maximum(int left, int right)
{
return((left > right) ? left : right);
}
struct avl_node*
avl_tree_print(struct avl_node* root, int levels)
{
int i;
if(root != NULL) {
avl_tree_print(root->right,levels);
if (root->depth < levels) {
for (i = 0; i < root->depth; i++) {
printf(" ");
}
printf("%i\n",root->data);
}
avl_tree_print(root->left,levels);
}
}
struct avl_node*
avl_tree_find_minimum(struct avl_node* root)
{
if(root == NULL) {
return NULL;
}
if(root->left == NULL) {
return root;
} else {
return avl_tree_find_minimum(root->left);
}
}
struct avl_node*
avl_tree_find_maximum(struct avl_node* root)
{
if(root != NULL) {
while(root->right != NULL) {
root = root->right;
}
}
return root;
}
struct avl_node*
avl_tree_subtract_depth(struct avl_node* root)
{
if(root == NULL) {
return NULL;
}
root->depth--;
avl_tree_subtract_depth(root->left);
avl_tree_subtract_depth(root->right);
}
struct avl_node*
avl_tree_add_depth(struct avl_node* root)
{
if (root == NULL) {
return NULL;
}
root->depth++;
avl_tree_add_depth(root->left);
avl_tree_add_depth(root->right);
}
struct avl_node*
avl_tree_rotate_left_left(struct avl_node* root)
{
/*
* Single Rotation (LL)
*
* r nr
* / \ / \
* nr -> left r
* / \ / \ / \
* left
*
*/
struct avl_node* new_root;
new_root = root->left;
root->left = new_root->right;
new_root->right = root;
root->depth++;
new_root->depth--;
avl_tree_add_depth(root->right);
avl_tree_subtract_depth(new_root->left);
root->height = maximum(height(root->left),height(root->right))+1;
new_root->height = maximum(height(new_root->left),root->height)+1;
return new_root;
}
struct avl_node*
avl_tree_rotate_right_right(struct avl_node* root)
{
/*
* Single Rotation (RR)
*
* r nr
* / \ / \
* nr -> r right
* / \ / \ / \
* right
*
*/
struct avl_node* new_root;
new_root = root->right;
root->right = new_root->left;
new_root->left = root;
root->depth++;
new_root->depth--;
avl_tree_add_depth(root->left);
avl_tree_subtract_depth(new_root->right);
root->height = maximum(height(root->left),height(root->right))+1;
new_root->height = maximum(height(new_root->right),root->height)+1;
return new_root;
}
struct avl_node*
avl_tree_rotate_left_right(struct avl_node* root)
{
/*
* Double Rotation (LR)
*
* r r nr
* / \ / \ / \
* A nr A r
* / \ -> / \ -> / \ / \
* nr A
* / \ / \
*
*/
root->left = avl_tree_rotate_right_right(root->left);
root = avl_tree_rotate_left_left(root);
return(root);
}
struct avl_node*
avl_tree_rotate_right_left(struct avl_node* root)
{
/*
* Double Rotation (RL)
*
* r r nr
* / \ / \ / \
* A nr r A
* / \ -> / \ -> / \ / \
* nr A
* / \ / \
*
*/
root->right = avl_tree_rotate_left_left(root->right);
root = avl_tree_rotate_right_right(root);
return(root);
}
struct avl_node*
avl_tree_insert(struct avl_node* root, int data, int depth)
{
if(root == NULL) {
root = (struct avl_node*)malloc(sizeof(struct avl_node));
if(root == NULL) {
printf("Out of memory");
exit(0);
} else {
root->data = data;
root->depth = depth;
root->height = 0;
root->left = NULL;
root->right = NULL;
}
} else if(data < root->data) {
root->left = avl_tree_insert(root->left,data,depth+1);
if(height(root->left)-height(root->right) > 1) {
if(data < root->left->data) {
root = avl_tree_rotate_left_left(root);
} else {
root = avl_tree_rotate_left_right(root);
}
}
} else if(data > root->data) {
root->right = avl_tree_insert(root->right,data,depth+1);
if(height(root->right)-height(root->left) > 1) {
if(data > root->right->data) {
root = avl_tree_rotate_right_right(root);
} else {
root = avl_tree_rotate_right_left(root);
}
}
}
root->height = maximum(height(root->left),height(root->right))+1;
return(root);
}
struct avl_node*
avl_tree_delete(struct avl_node* root,int data)
{
struct avl_node* new_root;
if (root == NULL) {
return NULL;
}
if(root->data > data) {
root->left = avl_tree_delete(root->left,data);
if(height(root->right)-height(root->left) > 1) {
if(data < root->right->data) {
root = avl_tree_rotate_right_right(root);
} else {
root = avl_tree_rotate_right_left(root);
}
}
} else if(root->data < data) {
root->right = avl_tree_delete(root->right,data);
if(height(root->left)-height(root->right) > 1) {
if(data > root->left->data) {
root = avl_tree_rotate_left_left(root);
} else {
root = avl_tree_rotate_left_right(root);
}
}
} else if(root->data == data) {
new_root = root;
if(new_root->right == NULL) {
root = new_root->left;
free(new_root);
} else if(new_root->left == NULL) {
root = new_root->right;
free(new_root);
} else {
new_root = avl_tree_find_minimum(new_root->right);
root->data = new_root->data;
root = new_root->right;
free(new_root);
}
}
if (root != NULL) {
root->height =maximum(height(root->left),height(root->right))+1;
}
return(root);
}
int
main(int argc, char** argv) {
int i;
struct avl_node* root = NULL;
for(i = 0; i < 1000000; i++) {
root = avl_tree_insert(root,rand()%1000000,0);
}
printf("AVL tree created:\n");
printf("Node count:\t%i\n",avl_tree_node_count(root));
printf("Tree height:\t%i\n",root->height);
printf("-----------------------------\n");
avl_tree_print(root,4);
printf("-----------------------------\n");
sleep(2);
printf("Deleting the root node, %i\n",root->data);
printf("-----------------------------\n");
sleep(2);
avl_tree_delete(root,root->data);
avl_tree_print(root,4);
}
