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); }