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