AVL Trees A BST in which, for any node, the number of levels in its two subtrees differ by at most 1 The height of an empty tree is -1. If this relationship changes after insertion or deletion, rebalancing is performed
AVL Trees: Balancing Factor BF(T) Definition: The balance factor, BF(T), of a node T in a binary tree is defined to be hR - hL, where hR and hL , respectively, are the heights of the right and left subtrees of T. For any node T in an AVL tree: BF(T) = -1, 0 or 1 Maintaining balance after insertion/deletion: must update all the balancing information for nodes on path back to the root; if balance factor becomes -2 or +2, rebalancing (referred to as rotation) is required insertion into AVL tree with zero or one node cannot cause an imbalance
Rebalancing Scenarios and Corresponding Rotation Methods Single Last: the first unbalanced node (a) on the path from the insertion point towards the root RR: X is inserted in right subtree of right subtree of a. LL: new node X is inserted in left subtree of left subtree of a. LL RR RR Operations (Left Rotation): Last = a Q = Last->right; Last->right = Q->left; Last = Q: LL Operations (Right Rotation): Last = a Q = Last->left; Last->left = Q->right; Last = Q:
Rebalancing Scenarios and Corresponding Rotation Methods Double LR: X is inserted in right subtree of left subtree of A RL: X is inserted in left subtree of right subtree of A LR Operations (Left-Right Rotation): Last = a Q = Last->left T =Q->right Q->right = T->left Last->left = T T-left = Q Last->left = T->right Last = T RL Operations (Right-Left Rotation): Last = a Q = Last->right T =Q->left Q->left = T->right Last->right = T T-right = Q Last->right = T->left Last = T
Balancing Properties Only nodes with balance values +1 and -1 can become unbalanced due to insertion Only nodes on search path between inserted node and the unbalanced node will need to have their balance fields updated Rotations have 2 properties: the inorder of the elements remains the same after the rotation as before the overall height of the tree is the same after the rotation as it was before the insertion Procedures change pointer in local root node so it points to root of new subtree
Algorithm for Insertion Attach new node as in Binary Search Tree Travel up the tree, searching for pivot node (node whose balance is either +1 or -1 and is closest to new node), updating balance info at every node on the path If path ends at root without having found any imbalanced nodes, we are done; Else do a rotation at pivot node and adjust its balance. Observations: For the balance factor of a node X to become +2, it must have been +1 before the insertion. Thus, before insertion, balance factors of all nodes on the path from X to the new insertion point must have been 0. If insertion did not result in an unbalanced tree, even though some path length increased by 1, it must be that the new balance factor of X is 0.
Example: Example: Insertion of 70, 40, 83, 35, 55, 80, 83, 85, 17, 37, 50, 60, 81, 100, 45, 53 into initially empty AVL Inserting successors of 45, 53, 81 or 100 will cause imbalance in the tree
Example: continued Insert 43: left child of left subtree --- single right rotation after right rotation
Example: continued Insert 54: right child of the left subtree -- double LR rotation after left rotation after right rotation
Example: continued Insert 82: right child of the right subtree -- Single left rotation after left rotation Insert 110, 93 and 54
Delete Basic algorithm Delete the node as in simple binary search tree. Retrace search path from deleted node back to root. If an imbalance occurs, perform rotation(s) until tree is balanced Deletion can require 1.44 log(n+2) rebalances in worst case, while insertion can require at most one rebalance The average case takes log n + .25 searches, which reduces the number of rotations in case of deletions to log n + .25 Experiments indicate that deletions in 78% of cases cause no rebalancing, while only 25% of insertions do not cause imbalance. More costly deletions occur less often Lazy deletion is best if deletions are infrequent
Delete Example Delete 12: Rotate Left 9 Rotate Right 11
Delete Rotate Right 8
AVL Tree: Analysis Let’s denote the number of nodes,n, in an AVL tree of height h by n(h). In the following we show that the height, h, of an an AVL tree is bounded by O(log n(h)). Using AVL tree property we can say that at least n(h) = n(h-1) + n(h-2) + 1 Using the above relationship, we can also say that n(h-1) > n(h-2) Substituting n(h-1) and dropping the 1 above, we rewrite: n(h) > 2 n(h-2) Similarly we can write n(h-2) > 2 n(h-4) and n(h-4) > 2 n(h-6) Scoping these terms in the equation for n(h) n(h) > 2 (2 n(h-4)) n(h) > 2 (2 (2n(h-6)) n(h) > 8 n(h-6) The above equations can be generalized as follows: n(h) > 2in(h-2i) Since we know the base cases of AVL tree n(0) = 1 and n(1) = 2, we get i = h/2 -1 Therefore replacing i in the equation for n(h), n(h) > 2 h/2 -1 x 1 Taking log on both sides yields h = O(log n(h)) QED
AVL Node Implementation in C++ Using BST Class /*1*/ template <class Etype> /*2*/ class AvlNode : public TreeNode<Etype> /*3*/ { /*4*/ private: /*5*/ int height; /*6*/ friend int NodeHt ( AvlNode * P) /*7*/ friend int NodeHt ( TreeNode<Etype>* P ) /*8*/ friend void CalculateHeight ( AvlNode* P ) /*9*/ friend void SRotateLeft ( AvlNode* & k2 ); /*10*/ friend void DRotateLeft ( AvlNode* & k3 ); /*11*/ friend void SRotateRight ( AvlNode* & k1 ); /*12*/ friend void DRotateRight ( AvlNode* & k3 ); /*13*/ public: /*14*/ AvlNode ( Etype E=0, AvlNode* L = NULL, AvlNode* R=NULL, int H=0 ); /*15*/ };