1 / 18

AVL Trees II

AVL Trees II. Implementation. 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.

Download Presentation

AVL Trees II

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. AVL Trees II Implementation

  2. 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

  3. Explore the Code • Enums used to specify direction of descent and kind of rotation needed • In AVL_BST.h enum direction {dir_left, dir_right, dir_none}; enum rotation_type { rotate_type_left, rotate_type_right, rotate_type_left_right, rotate_type_right_left };

  4. New Node Class template<typename T> class AvlNode { public: AvlNode() { level = position = left = right = 0; } AvlNode(const T& el, AvlNode *l = 0, AvlNode *r = 0) { data = el; left = l; right = r; level = position = 0; } T data; int balance_factor; int position; int level; AvlNode *left, *right; };

  5. Class AVL_BST • The insert method has been changed (radically) in order to implement AVL tree rebalancing. • Now a recursive method. • Public method declaration unchanged: void insert(const T&); • New internal method: void insert(const T& item, // Input AvlNode<T>** incoming_ptr, // Input bool& subtree_height_increased, // Output direction& dir); // Output

  6. Public Insert Method // Public insert method template <typename T> void AVL_BST<T>::insert(const T& item) { // Return values from internal insert method. Not used here. bool childs_subtree_height_increased; direction childs_direction; if (root == 0) { // Inserting into an empty tree. root = new AvlNode<T>(item); } else { insert(item, &root, childs_subtree_height_increased, childs_direction); } }

  7. Internal insert method // Internal (protected) insert method template <typename T> void AVL_BST<T>::insert(const T& item, // Input AvlNode<T>** incoming_ptr, // Input bool& subtree_height_increased, // Output direction& dir) // Output { AvlNode<T>* node = *incoming_ptr; // Current node if (item < node->data) { dir = dir_left; if (node->left == 0) { insert_left(item, incoming_ptr, subtree_height_increased, dir); } else { descend_left(item, incoming_ptr, subtree_height_increased, dir); } } ...

  8. Internal insert method (continued) else if (node->data < item) { dir = dir_right; if (node->right == 0) { insert_right(item, incoming_ptr, subtree_height_increased, dir); } else { descend_right(item, incoming_ptr, subtree_height_increased, dir); } } else // Item found. (Shouldn't happen) { throw "Attempt to add an item already in the tree"; } } Symmetrical to > case

  9. insert_right template <typename T> void AVL_BST<T>::insert_right(const T & item, // Input AvlNode<T>** incoming_ptr, // Input bool& subtree_height_increased, // Output direction& dir) // Output { AvlNode<T>* node = *incoming_ptr; // Current node cout << endl << "Inserting " << item << " at " << node->data << " as right child" << endl; assert(node->right == 0); node->right = new AvlNode<T>(item); ... Insert new node into tree.

  10. insert_right (continued) dir = dir_right; if (node->left == 0) { // This node was previously a leaf. subtree_height_increased = true; node->balance_factor = -1; } else { // Already had a left child, so no increase. subtree_height_increased = false; node->balance_factor = 0; } } Report back to caller.

  11. descend_right template <typename T> void AVL_BST<T>::descend_right(const T& item, // Input AvlNode<T>** incoming_ptr, // Input bool& subtree_height_increased, // Output direction& dir) // Output { bool childs_subtree_height_increased; // Set by call to insert direction childs_direction; // Set by call to insert AvlNode<T>*node = *incoming_ptr; // Current node assert(node->right != 0); insert(item, &(node->right), childs_subtree_height_increased, childs_direction); dir = dir_right; if (!childs_subtree_height_increased) { subtree_height_increased = false; return; } Recursive call Report back to caller

  12. descend_right (continued) // Child's subtree height increased due to inserting the new node. --node->balance_factor; if (node->balance_factor < -1) { cout << endl << node->data << " requires rebalance" << endl; display_v(cout, 4); if (childs_direction == dir_right) { rotate_left(incoming_ptr); } else { rotate_right_left(incoming_ptr); } cout << endl << "After rotation: " << endl << endl; display_v(cout, 4); // After rotation, subtree height has not increased subtree_height_increased = false; return; } Report back to caller

  13. descend_right (continued) // No rotation at this level. if (node->balance_factor == -1) { subtree_height_increased = true; } else { subtree_height_increased = false; } } Report back to caller

  14. rotate_right template <typename T> void AVL_BST<T>::rotate_right(AvlNode<T>** parent_link) { AvlNode<T>* node = *parent_link; cout << endl << node->data << " rotate_right " << endl; assert(node->left != 0); AvlNode<T>* temp = node->left->right; AvlNode<T>* pivot = node->left; pivot->right = *parent_link; *parent_link = pivot; node->left = temp; update_balance_factor(pivot); update_balance_factor(node); } "pivot" is the left child of the node being rotated to the right. It will take the place of the node being rotated, and the node being rotated will become its right child. If it previously had a right child, that node will become the new left child of the node being rotated.

  15. update_balance_factor template <typename T> void AVL_BST<T>::update_balance_factor(AvlNode<T>* node) { if (node->right == 0) { if (node->left == 0) { node->balance_factor = 0; } else { node->balance_factor = 1; } } else ... Update the balance factor of a node that has just been rotated. There are only three possible values

  16. update_balance_factor else { if (node->left == 0) { node->balance_factor = -1; } else { int l = height(node->left); int r = height(node->right); assert (abs(l-r) < 2); node->balance_factor = l - r; } } } node has a right child. node has a right child and a left child.

  17. Compute height of a subtree template <typename T> int AVL_BST<T>::height(AvlNode<T>* node) { int left_child_height = node->left ? height(node->left) : 0; int right_child_height = node->right ? height(node->right) : 0; return max(left_child_height, right_child_height) + 1; }

  18. Assignment • Study the AVL_BST code carefully. • Try it with your own test cases. • Try to find errors. • Major bragging rights to a student who reports a significant bug. • Be prepared to answer questions about it.

More Related