300 likes | 372 Views
AVL Trees II. Implementation. AVL Tree ADT. A binary search tree in which the balance factor of each node is 0, 1, of -1. Basic Operations Construction, empty, search, and traverse are the same as for a BST. Insert a new item in such a way that the height-balanced property is maintained.
E N D
AVL Trees II Implementation
AVL Tree ADT • A binary search tree in which the balance factor of each node is 0, 1, of -1. • Basic Operations • Construction, empty, search, and traverse are the same as for a BST. • Insert a new item in such a way that the height-balanced property is maintained. • Delete a item in such a way that the height-balanced property is maintained. • Left for advanced course! • Discussed in Brozdek.
AVL Trees • Class to represent AVL tree nodes • Includes new data member for the balance factor
What do we need to know? • When we look at a tree on paper, it is fairly easy to determine if the tree has become unbalanced. • Also what to do to fix the problem. • When implementing the ADT, we have to work with local information. • What do we have available as we descend the tree to add a node and return? • What do we need to know at each node?
Observations • When we add a node to an AVL tree, the parent node will either be a leaf or have a single child. • If the parent node is a leaf, its balance factor prior to the addition is 0. • After the addition, the balance factor absolute value will be 1. • Ancestor nodes’ balance factor may increase, decrease, or remain the same. • Rebalancing may or may not be necessary. • If the parent node has a single child, its absolute balance factor prior to the addition will be 1. • After the addition, it will be 0. • Ancestor nodes’ balance factors will not change. • Rebalancing will not be necessary.
Observations Given that the tree was an admissible AVL tree before we added a node: • Adding a node always changes the balance factor of the parent of the new node. • Absolute value 0 to 1 or 1 to 0. • The parent node will never become unbalanced due to an addition. • The grandparent is the first node (going up the tree) that can become unbalanced due to an addition. • An ancestor further up the tree could be the first node to become unbalanced. • See addition of MA in previous presentation.
When does a node become unbalanced? • A node will become unbalanced due to an addition if the following conditions are true: • It already had an balance factor of +1 or -1. • In searching for the point to do the addition we descended into its subtree that already had the greater height. • Left subtree if balance factor was +1. • Right subtree is balance factor was -1. • Adding the node increased the height of that subtree. • We need to know if adding a node to a subtree increased the height of the subtree.
Did the subtree height increase? • We need to know if adding a node to a subtree increased the height of the subtree. • The (recursive) insert function must report back to its caller whether adding a new node increased the height of the subtree to which it was added. • At each step we can then determine if the node has become unbalanced. • Whether or not we need to do a rotation.
When does a node become unbalanced? • Adding a node increased the height of the subtree at a node along the path from the new node back to the root if: • The addition increased the height of the subtree rooted at the parent of the new node. • We added the node to a leaf. • The addition increased the height of the subtree rooted at each intermediate node. • Balance factor at each intermediate node was 0 • If a node previously had a nonzero balance factor and adding the new node increased the height of its higher subtree, the addition made that node unbalanced.
Rebalancing the Tree • If adding a node increased the height of a subtree and any node became unbalanced because of the increase, we will do a rotation at the nearest ancestor that became unbalanced. • The rotation reduces the height of the subtree rooted at that position. • Will ensure that the subtree at that position does not increase in height. • No further rotations will be needed.
Rebalancing the Tree • We will use a recursive search to find the node at which to attach the new node. • Previously we used a loop. • When we find the place to attach the new node, after attaching it, return values saying • Whether or not the subtree height increased. • On which side the new node was added. • Required in order to determine if a double rotation is needed.
Rebalancing the Tree • At each step in the sequence of recursive calls, report back the same information: • Did the subtree rooted at this position increase in height? • Which direction did we descend to do the addition?
Rebalancing the Tree • At each node as we descend from the root • If the balance factor is nonzero • If we descended in the direction of our higher subtree • If the next node down reports back that the height of its subtree increased • This node has become unbalanced. • We must do a rotation at this node.
Rebalancing the Tree • If we have to do a rotation • If the next node down reports that it descended in the same direction • Do a single rotation. • Else • Do a double rotation.
Implementation • Download: • http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_03_28_AVL_Tree/ File AVL_Tree_Demo.zip • Project contains: • AVL_BST.h Our most recent BST template updated to implement an AVL tree. • main.cpp Uses the AVL BST to replicate the states example from last class. • Extract, build, and run