We introduced binary trees in lecture 19. For completeness, the code is repeated here. We left off while still busy deleting elements from a tree, but will continue with this and balancing in the next lecture.
/* L-19 MCS 360 Wed 26 Feb 2003
* declaration of a binary tree,
* implemented with pointers to nodes */
#define elements int
typedef struct node tree; /* a tree starts at the root node */
struct node
{
elements info; /* data field of the node */
tree *left; /* pointer to the left child */
tree *right; /* pointer to the right child */
};
int empty ( tree *t );
/* postcondition: returns 1 if tree is empty, 0 otherwise; */
elements info ( tree *t );
/* precondition: empty(t) = 0;
* postcondition: info(t) is the content of the node t; */
tree *create ( elements e );
/* postcondition: info(create(e)) == e; */
tree *left ( tree *t );
/* precondition: empty(t) == 0;
* postcondition: left(t) is left child of t; */
tree *right ( tree *t );
/* precondition: empty(t) == 0;
* postcondition: right(t) is right child of t; */
void *add_left ( tree *t, tree *child );
/* precondition: empty(t) == 0;
* postcondition: left(t) == child; */
void *add_right ( tree *t, tree *child );
/* precondition: empty(t) == 0;
* postcondition: right(t) == child; */
void destroy ( tree *t );
/* postcondition: empty(t) == 1; */
/* L-19 MCS 360 Wed 26 Feb 2003
* definition of the operations on a tree,
* implemented with pointers to nodes */
#include <stdlib.h>
#include <assert.h>
#include "tree.h"
int empty ( tree *t )
{
return (t == NULL ? 1 : 0);
}
elements info ( tree *t )
{
assert(empty(t) == 0);
return t->info;
}
tree *create ( elements e )
{
tree *t;
t = (tree*)calloc(1,sizeof(tree));
t->info = e;
t->left = NULL;
t->right = NULL;
return t;
}
tree *left ( tree *t )
{
assert(empty(t) == 0);
return t->left;
}
tree *right ( tree *t )
{
assert(empty(t) == 0);
return t->right;
}
void *add_left ( tree *t, tree *child )
{
assert(empty(t) == 0);
t->left = child;
}
void *add_right ( tree *t, tree *child )
{
assert(empty(t) == 0);
t->right = child;
}
void destroy ( tree *t )
{
free(t);
}
/* L-37 MCS 360 Wednesday 16 April 2003 * Prototypes for a table to store positive integers. */ #include <stdio.h> #include "tree.h" tree *insert_element ( tree *t, int n ); /* inserts n into the tree, * except if n already occurs, * then a message is printed */ tree *search_element ( tree *t, int n ); /* returns null if n does not occur in t, * otherwise returns t with info(t) == n */ tree *delete_element ( tree *t, int n ); /* delete_elements the node in the tree with info == n */
/* L-37 MCS 360 Wednesday 16 April 2003
* Definitions of the most essential operations on a table. */
#include <stdio.h>
#include "table.h"
tree *insert_element ( tree *t, int n )
{
if (empty(t) == 1)
t = create(n);
else if (info(t) > n)
add_left(t,insert_element(left(t),n));
else if (info(t) < n)
add_right(t,insert_element(right(t),n));
else
printf("found duplicate number %d\n", n);
return t;
}
tree *search_element ( tree *t, int n )
{
tree *p = t;
while ((p != NULL) && (info(p) != n))
p = ( n < info(p) ? left(p) : right(p) );
return p;
}
tree *delete_element ( tree *t, int n )
{
tree *p = t;
tree *father = NULL;
while ((p != NULL) && (info(p) != n)) /* search for n */
{
father = p;
p = ( n < info(p) ? left(p) : right(p) );
}
if (p == NULL)
return t;
else /* p must be deleted */
{
tree *replacement; /* search replacement */
if (left(p) == NULL)
replacement = right(p);
else if (right(p) == NULL)
replacement = left(p);
else /* p has two sons */
{
tree *son,*f = p;
replacement = right(p); /* find inorder successor */
son = left(replacement);
while (son != NULL)
{
f = replacement;
replacement = son;
son = left(replacement);
} /* replacement == inorder successor */
if (f != p) /* father of replacement is not p */
{
add_left(f,right(replacement));
add_right(replacement,right(p));
} /* left(replacement) is always NULL */
add_left(replacement,left(p));
}
if (father == NULL) /* p == root of tree */
t = replacement;
else if (p == left(father)) /* p is left child */
add_left(father,replacement);
else /* p is right child */
add_right(father,replacement);
free(p);
return t;
}
}
/* L-37 MCS 360 Wednesday 16 April 2003
*
* This program is an extension of that of lecture 19 where
* a binary tree implemented with pointers was used to remove
* duplicates from a list of positive integers.
*
* The operations in this program illustrate balancing of trees. */
#include <stdio.h>
#include "table.h"
int height ( tree *t );
/* returns the height of the tree */
int balance ( tree *t );
/* returns the height(left(t)) - height(right(t)) */
tree *left_rotate ( tree *t );
/* performs one left rotation on the tree t */
tree *right_rotate ( tree *t );
/* performs one right rotation on the tree t */
tree *rebalance ( tree *t );
/* computes the balance of the root, and does one
* rotation to the left or right to rebalance */
void write ( tree *t, int level );
/* writes the content of the tree,
* traversing the tree in preorder,
* using level to make intendations */
int main ( void )
{
tree *t = NULL;
int n;
do
{
printf("Give integers (<0 to stop) : ");
scanf("%d", &n);
if (n < 0) break;
t = insert_element(t,n);
} while (n >= 0);
printf("The tree of numbers : \n");
write(t,0);
do
{
printf("Give integer to search for (<0 to stop) : ");
scanf("%d", &n);
if (n < 0) break;
if (search_element(t,n) == NULL)
{
printf("%d does not occur in the tree\n", n);
t = insert_element(t,n);
printf("tree after insertion of %d :\n", n);
write(t,0);
}
else
{
printf("%d does occur in the tree\n", n);
t = delete_element(t,n);
printf("tree after deletion of %d :\n", n);
write(t,0);
}
t = rebalance(t);
printf("tree after rebalancing : \n");
write(t,0);
} while (n >= 0);
return 0;
}
int height ( tree *t )
{
if (t == NULL)
return -1;
else
{
int hl = 1 + height(left(t));
int hr = 1 + height(right(t));
if (hl > hr)
return hl;
else
return hr;
}
}
int balance ( tree *t )
{
if (t == NULL)
return 0;
else
return height(left(t)) - height(right(t));
}
tree *left_rotate ( tree *t )
{
if (t != NULL)
{
tree *p = right(t);
if (p != NULL)
{
tree *tmp = left(p);
add_left(p,t);
add_right(t,tmp);
t = p;
}
}
return t;
}
tree *right_rotate ( tree *t )
{
if (t != NULL)
{
tree *p = left(t);
if (p != NULL)
{
tree *tmp = right(p);
add_right(p,t);
add_left(t,tmp);
t = p;
}
}
return t;
}
tree *rebalance ( tree *t )
{
if (t != NULL)
{
int bal = balance(t);
if (bal < 0)
t = left_rotate(t);
else if (bal > 0)
t = right_rotate(t);
}
}
void write ( tree *t, int level )
{
if (empty(t) == 0)
{
int i;
for (i=0; i<level; i++) printf(" ");
printf("%d height = %d balance = %d\n",
info(t), height(t), balance(t));
write(left(t),level+1);
write(right(t),level+1);
}
}