Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 AVL Trees II Implementation. 2 Download: 2011_03_28_AVL_Tree/ File AVL_Tree_Demo.zip

Similar presentations


Presentation on theme: "1 AVL Trees II Implementation. 2 Download: 2011_03_28_AVL_Tree/ File AVL_Tree_Demo.zip"— Presentation transcript:

1 1 AVL Trees II Implementation

2 2 Download: http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/ 2011_03_28_AVL_Tree/ File AVL_Tree_Demo.zip http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/ 2011_03_28_AVL_Tree/ 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 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 4 New Node Class template 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 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 ** incoming_ptr, // Input bool& subtree_height_increased, // Output direction& dir); // Output

6 6 Public Insert Method // Public insert method template void AVL_BST ::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 (item); } else { insert(item, &root, childs_subtree_height_increased, childs_direction); }

7 7 Internal insert method // Internal (protected) insert method template void AVL_BST ::insert(const T& item, // Input AvlNode ** incoming_ptr, // Input bool& subtree_height_increased, // Output direction& dir) // Output { AvlNode * node = *incoming_ptr; // Current node if (item 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 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 9 insert_right template void AVL_BST ::insert_right(const T & item, // Input AvlNode ** incoming_ptr, // Input bool& subtree_height_increased, // Output direction& dir) // Output { AvlNode * node = *incoming_ptr; // Current node cout data << " as right child" << endl; assert(node->right == 0); node->right = new AvlNode (item);... Insert new node into tree.

10 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 11 descend_right template void AVL_BST ::descend_right(const T& item, // Input AvlNode ** 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 *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 12 descend_right (continued) // Child's subtree height increased due to inserting the new node. --node->balance_factor; if (node->balance_factor < -1) { cout 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 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 14 rotate_right template void AVL_BST ::rotate_right(AvlNode ** parent_link) { AvlNode * node = *parent_link; cout data << " rotate_right " << endl; assert(node->left != 0); AvlNode * temp = node->left->right; AvlNode * 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 15 update_balance_factor template void AVL_BST ::update_balance_factor(AvlNode * 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 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 17 Compute height of a subtree template int AVL_BST ::height(AvlNode * 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 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.


Download ppt "1 AVL Trees II Implementation. 2 Download: 2011_03_28_AVL_Tree/ File AVL_Tree_Demo.zip"

Similar presentations


Ads by Google