5.AVL TREES (HEIGHT-BALANCED TREE) The efficiency of various operations on binary search tree decreases with increase in the difference between the heights of right subtree and left subtree of the root node. Hence, the difference between the heights of left subtree and right subtree should be kept to the minimum. Various operations performed on binary tree can lead to an unbalanced tree, in which either the height of left subtree is much more than the height of right subtree or vice versa. Such type of tree must be balanced using some techniques to achieve better efficiency level. The need to have balanced tree led to the emergence of another type of binary search tree known as AVL tree. AVL tree also known as height-balanced tree is a special kind of binary search tree,which satisfies the following two conditions: 1.The heights of the left and right subtrees of a node differ by at most one. 2.The left and right subtrees of a node (if exist) are also AVL trees. AVL TREES (HEIGHT-BALANCED TREE) The term balancing factor is used to determine whether the given binary search tree is balanced or not. The balancing factor of a node is calculated as the height of its left subtree minus height of right subtree. Different values of balancing factor (BF), indicate The following (see Figure 6.20, value written adjacent to node is its BF): 1. BF = 0, if the binary search tree is perfectly balanced, that is, both left subtree and right subtree are of same height. 2. BF = +1, if the height of left subtree is one greater than the height of right subtree. 3. BF = -1, if the height of right subtree is one greater than the height of left subtree. 4. BF <= -2 and BF >= +2, the binary search tree is said to be unbalanced as there is unacceptable difference between the heights of left subtree and right subtree. Thus, it is clear that for an AVL tree, the value of BF for a node can be -1, 0 or 1. AVL TREES (HEIGHT-BALANCED TREE) To define a node of the AVL tree in C language, a self- referential structure can be used. typedef struct node { int info; struct node *left; struct node *right; int Bfact; }Node; Inserting a node in AVL tree Insertion of a node in the tree may or may not result in an unbalanced tree. For example, the insertion of two more elements 25 and 35 in the balanced tree shown in Figure 6.20(a) results in an unbalanced tree (see Figure 6.20(b)). Inserting a node in AVL tree Certain situations, in which insertion of a node does not result in an unbalanced tree, are as follows: • If the node is inserted as a child node of the node (non-leaf node) already having one child node. • If the node is inserted in the subtree of lesser height. • If the node is inserted in a tree, having both the subtrees of same height. If node is inserted as a child node of a leaf node belonging to a longer subtree, it may further increase the height of the longer subtree making the tree unbalanced. To convert an unbalanced tree into a balanced tree, some techniques known as rotations are used. Depending upon the position of the newly inserted node, the tree may require either single or double rotation. Inserting a node in AVL tree Single rotations: In single rotation, tree is either rotated towards right or towards left. In reference to the node R of a binary search tree T, single rotation is required in two cases. First, when node is inserted in the left subtree of left subtree of node R and second, when node is inserted in the right subtree of right subtree of node R. In first case the tree becomes left heavy (height of left subtree is one more than the required height) and requires single right rotation. In second case, the tree becomes right heavy (height of right subtree is one more than the required height) and requires single left rotation. Inserting a node in AVL tree Right Rotation: For understanding single right rotation, consider the balanced tree shown in Figure 6.21(a). Insertion of the node with value 25, results in an unbalanced (left heavy tree) tree as shown in Figure 6.21(b). To make this tree balanced, the tree is rotated towards right for once along the node 66. The resultant balanced tree is shown in Figure 6.21 (c). Inserting a node in AVL tree Double rotations: Double rotations are required when a single rotat.on ,s not enough and more rotat.ons are required to make the tree balanced. In these types of rotations, either the left rotation is followed by right rotation or vice versa. 6.THREADED BINARY TREE One of the most common operations that are performed on the trees is traversal of nodes. Hence, It is required to make this operation more efficient. This can be achieved by utilizing space occupied by the NULL pointers in the leaf nodes and internal node having only one child node. These pointers can be modified to point to their corresponding inorder successor, in-order predecessor or both. These modified pointers are known as threads and binary trees having such type of pointers are known as threaded binary tree. The different types of threaded binary trees are s (see Figure 6.25, threads are denoted by dotted lines): Right-threaded binary tree In this tree, the right NULL pointer of each node (not having right child node) points to its in-order successor. Such a right NULL pointer is known as right thread. In this tree, only the right pointer of the rightmost node (F, see Figure 6.25(a)) will be a NULL pointer and all the left NULL pointers will remain NULL. Left-threaded binary tree In this tree, the left NULL pointer of each node (not having left child node) points to its in-order predecessor. Such a left NULL pointer is known as left thread. In this tree, only the left pointer of the leftmost node (G, sec Figure 6.25(b)) will be a NULL pointer and all right NULL pointers will remain NULL. Full-threaded binary tree In this tree, both right and left NULL pointer points to its in- order successor and in-order predecessor, respectively. In this tree, both the right pointer of rightmost node (F) and the left pointer of the leftmost node (G) will be a NULL pointer (see Figure 6.25(c)). Storage Representation of Threaded Binary Tree To define a node of a full-threaded binary tree in C language, a self-referential structure can be used whose definition is shown here. The variables lthread and rthread are used to indicate whether the left and right pointers are normal pointers or threads. The value ‘1’ is stored in these variables to indicate that the corresponding left and right pointers are normal pointers and value ‘0' indicates that the corresponding variables will be used as threads. 7.WEIGHT-BALANCED TREES In a weight-balanced tree, the nodes are arranged on the basis of the knowledge available on the probability for searching each node. The node with highest probability is placed at the root of the tree. The nodes in the left subtree of such a tree are less in ranking as well as are less in probability than the root node and the nodes in right subtree are higher in ranking than the root node (see Figure 6.27). In this figure, the node with ranking P is root node of the tree since it has highest probability. The left subtree starts with node having ranking E since E is less than P and has the highest probability among all the nodes of the left subtree. The right subtree starts with node having ranking T since it is greater than P and has the highest probability among all the nodes of right subtree. 8.APPLICATIONS OF TREES Set Representation A set is said to be a collection of unique elements of same type. The elements can be of any type like numbers, letters of alphabets, name of cities, etc. Such sets can be represented in the form of trees. For example, consider three disjoint sets (sets are disjoint when they have no common elements) S, P and R of integers, such that S = {2, 4, 6, 8 }, P =(3} and R = { 5, 9, 11}. These sets can be represented as trees (one tree for each set) as shown in Figure 6.28. Set Representation(Cont.) In this representation, one of the elements from set becomes a root node (also known as parent node) and all other elements from the set become its child nodes. All the child nodes have pointer pointing to their parent node (see Figure 6.28). The value at the ith position of the array is the parent node of ith node. The zero value in the array indicates the pointer to the root node. The array representation of the disjoint sets S, P and R is shown in Figure 6.29.