public class AVLTree> extends BST { protected int height; public AVLTree() { super(); height = -1; } public AVLTree(BTNode root) { super(root); height = -1; } public void purge(){ super.purge(); } public int getHeight() { return getHeight(root); } private int getHeight(BTNode node) { if(node == null) return -1; else return 1 + Math.max(getHeight(node.left), getHeight(node.right)); } private AVLTree getLeftAVL() { AVLTree leftsubtree = new AVLTree(root.left); return leftsubtree; } private AVLTree getRightAVL() { AVLTree rightsubtree = new AVLTree(root.right); return rightsubtree; } protected int getBalanceFactor() { if(isEmpty()) return 0; else return getRightAVL().getHeight() - getLeftAVL().getHeight(); } public void insertAVL(T el) { super.insert(el); this.balance(); } public void deleteAVL(T el) { // to be completed by students } protected void balance() { if(!isEmpty()) { getLeftAVL().balance(); getRightAVL().balance(); adjustHeight(); int balanceFactor = getBalanceFactor(); if(balanceFactor == -2) { System.out.println("Balance factor = " + balanceFactor); System.out.println("Balancing node with el: "+root.data); if(getRightAVL().getBalanceFactor() == 0 && getLeftAVL().getBalanceFactor() == -1) /// special case rotateRight(); else if(getLeftAVL().getBalanceFactor() <= 0) rotateRight(); else rotateLeftRight(); } else if(balanceFactor == 2) { System.out.println("Balance factor = " + balanceFactor); System.out.println("Balancing node with el: "+root.data); if(getRightAVL().getBalanceFactor() == 0) /// special case that cannot be done rotateLeft(); /// by double rotations else if(getRightAVL().getBalanceFactor() > 0) rotateLeft(); else rotateRightLeft(); } } } protected void adjustHeight() { if(isEmpty()) height = -1; else height = 1 + Math.max(getLeftAVL().getHeight(), getRightAVL().getHeight()); } protected void rotateRight() { System.out.println("RIGHT ROTATION"); // to be completed by students } protected void rotateLeft() { System.out.println("LEFT ROTATION"); BTNode tempNode = root.left; root.left = root.right; root.right = root.left.right; root.left.right = root.left.left; root.left.left = tempNode; T val = (T) root.data; root.data = root.left.data; root.left.data = val; getLeftAVL().adjustHeight(); adjustHeight(); } protected void rotateLeftRight() { System.out.println("Double Rotation..."); getLeftAVL().rotateLeft(); getLeftAVL().adjustHeight(); this.rotateRight(); this.adjustHeight(); } protected void rotateRightLeft() { System.out.println("Double Rotation..."); // to be completed by students } public void levelOrderTraversal(){ levelOrderTraversal(root); } } public class AVLTreeDriver { public static void main(String[] args) { System.out.println("\nSINGLE LEFT ROTATION EXAMPLE: "); System.out.println("Insert 45 in the following AVL tree:"); AVLTree avlTree2 = new AVLTree(); Integer[] array1 = new Integer []{30, 5, 35, 32, 40}; for(int i = 0; i < array1.length ; i++) avlTree2.insertAVL(array1[i]); avlTree2.printTree(); System.out.pri.