
We will first discuss how to maintain height information in a BST before we discuss AVL trees

public class BSTEntry { public String key; // Key public Integer value; // Value public int height; // Height information public BSTEntry parent; public BSTEntry left; public BSTEntry right; } 
Leaf node: Height( leaf node ) = 1 
Example:


Tree before insert operation  Tree after insert operation 

Tree before insert operation  Tree after insert operation 

Tree before delete operation  Tree after delete operation 

Tree before delete operation  Tree after delete operation 



Tree before insert operation  Tree after insert operation 

Tree before delete operation  Tree after delete operation 



we can write the following recompHeight() method:
/* ================================================================ recompHeight(x): recompute height starting at x (and up) ================================================================ */ public static void recompHeight( BSTEntry x ) { while ( x != null ) { x.height = maxHeight( x.left, x.right ) + 1; // Compute height for x x = x.parent; // Go to the parent node } } 



public void put(String k, Integer v) { BSTEntry p; // Help variable /*  Just like linked list, insert in an EMPTY BST must be taken care off separately by an ifstatement  */ if ( root == null ) { // Insert into an empty BST root = new BSTEntry( k, v ); root.height = 1; return; } /*  Find the node with key == "key" in the BST  */ p = findEntry(k); if ( k.equals( p.key ) ) { p.value = v; // Update value return; } /*  Insert a new entry (k,v) under p !!!  */ BSTEntry q = new BSTEntry( k, v ); q.height = 1; q.parent = p; /* ************************************************* Upto here, it's just the OLD put() method ************************************************* */ /*  Action location = q The parent of q = q So: recompute the height of all nodes starting at p  */ recompHeight(p); } 
public void remove(String k) { BSTEntry p, q; // Help variables BSTEntry parent; // parent node BSTEntry succ; // successor node /*  Find the node with key == "key" in the BST  */ p = findEntry(k); if ( ! k.equals( p.key ) ) return; // Not found ==> nothing to delete.... /* ======================================================== Hibbard's Algorithm ======================================================== */ if ( p.left == null && p.right == null ) // Case 0: p has no children { parent = p.parent; /*  Delete p from p's parent  */ if ( parent.left == p ) parent.left = null; else parent.right = null; /*  parent = parent of the deleted node Recompute height starting at "parent"...  */ recompHeight( parent ); return; } if ( p.left == null ) // Case 1a: p has 1 (right) child { parent = p.parent; /*  Link p's right child as p's parent child  */ if ( parent.left == p ) parent.left = p.right; else parent.right = p.right; /*  parent = parent of the deleted node Recompute height starting at "parent"...  */ recompHeight( parent ); return; } if ( p.right== null ) // Case 1b: p has 1 (left) child { parent = p.parent; /*  Link p's left child as p's parent child  */ if ( parent.left == p ) parent.left = p.left; else parent.right = p.left; /*  parent = parent of the deleted node Recompute height starting at "parent"...  */ recompHeight( parent ); return; } /* ================================================================ Tough case: node has 2 children  find successor of p succ(p) is as as follows: 1 step right, all the way left Note: succ(p) has NOT left child ! ================================================================ */ succ = p.right; // p has 2 children.... while ( succ.left != null ) succ = succ.left; p.key = succ.key; // Replace p with successor p.value = succ.value; /*  Delete succ from succ's parent  */ parent = succ.parent; if ( parent.left == succ ) parent.left = succ.right; // parent skip over succ ... else parent.right = succ.right; // ... and point to succ's right child /*  parent = parent of the deleted node Recompute height starting at "parent"...  */ recompHeight( parent ); return; } 
How to run the program:

Output:
[lion,9999](h=1) ================================ [lion,9999](h=2) [dog,1000](h=1) ================================ [lion,9999](h=3)* [dog,1000](h=2) [cat,500](h=1) ================================ [tiger,8888](h=1) [lion,9999](h=3) [dog,1000](h=2) [cat,500](h=1) ================================ [tiger,8888](h=1) [lion,9999](h=3) [horse,2000](h=1) [dog,1000](h=2) [cat,500](h=1) ================================ [tiger,8888](h=1) [lion,9999](h=4)* [horse,2000](h=1) [dog,1000](h=3) [cat,500](h=2) [ape,1500](h=1) 