#include "BinarySearchTree.h" #include using namespace std; template class AVLTree: public BinarySearchTree { protected: bool _isBalanced(typename BinaryTree::Iterator position) { int leftChildHeight, rightChildHeight, balanceFactor; //get left child's height if (position.hasLeftChild()) leftChildHeight = BinaryTree::_getAuxiliary(position.left()); else leftChildHeight = -1; //get right child's height if (position.hasRightChild()) rightChildHeight = BinaryTree::_getAuxiliary(position.right()); else rightChildHeight = -1; balanceFactor = rightChildHeight - leftChildHeight; return ((-1 <= balanceFactor) && (balanceFactor <= 1)); } void _setHeight(typename BinaryTree::Iterator position) { int leftChildHeight, rightChildHeight, newHeight; //get left child's height if (position.hasLeftChild()) leftChildHeight = BinaryTree::_getAuxiliary(position.left()); else leftChildHeight = -1; //get right child's height if (position.hasRightChild()) rightChildHeight = BinaryTree::_getAuxiliary(position.right()); else rightChildHeight = -1; if (rightChildHeight >= leftChildHeight) newHeight = rightChildHeight + 1; else newHeight = leftChildHeight + 1; _setAuxiliary(position, newHeight); } public: void insert(const ItemType& value) { cout << "inserting " << value << endl; //check if the new value should be the root if (BinaryTree::empty()) { _createRoot(value); _setHeight(BinaryTree::root()); } //it shouldn't be the root else { //insert the new value typename BinaryTree::Iterator current = BinaryTree::root(); typename BinaryTree::Iterator parent, grandparent; typename BinaryTree::Iterator x,y,z; bool done = false; while (!done) { if (*current <= value) { if (current.hasRightChild()) current = current.right(); else { _insertAsRightChild(current, value); _setHeight(current.right()); current = current.right(); done = true; } } else //going left if (current.hasLeftChild()) current = current.left(); else { _insertAsLeftChild(current, value); _setHeight(current.left()); current = current.left(); done = true; } } //fix balance factors and rotate parent = current.up(); _setHeight(parent); z = parent.up(); y = parent; x = current; while (z != BinaryTree::root().up()) { // determine x and y, and reset heights _setHeight(z); if (!_isBalanced(z)) { if (y == z.left() && x == y.left()) { BinaryTree::_pivot(y); _setHeight(z); _setHeight(y); z=y; } if (y == z.left() && x == y.right()) { BinaryTree::_pivot(x); BinaryTree::_pivot(x); _setHeight(y); _setHeight(z); _setHeight(x); z = x; } if (y == z.right() && x == y.left()) { BinaryTree::_pivot(x); BinaryTree::_pivot(x); _setHeight(y); _setHeight(z); _setHeight(x); z=x; } if (y == z.right() && x == y.right()) { BinaryTree::_pivot(y); _setHeight(z); _setHeight(y); z=y; } } //end if !z.isBalanced() //reset z x = y; y = z; z = z.up(); } //end while } } //end insert void remove(const ItemType& value) { //Program 5 } };