#ifndef AVLTREE_H #define AVLTREE_H #include <cstdlib> #include <iostream> template<class T> class AVLTree{ public: AVLTree():root(NULL){} AVLTree(const AVLTree& rhs) { *this = rhs; } const AVLTree& operator=(const AVLTree& rhs) { if(this != &rhs) { root = clone(rhs.root); } return *this; } ~AVLTree(){ makeEmpty(); } void insert(const T& x) { insert(x,root); } bool constain(const T& x)const { return constain(x,root); } const T& findMin()const { return findMin(root)->element; } const T& findMax()const { return findMax(root)->element; } bool isEmpty()const { return root == NULL; } void makeEmpty() { makeEmpty(root); } void printTree()const { printTree(root); } int Max(int a,int b)const { return (a > b) ? a : b; } private: /* Node in AVL Tree */ struct AVLNode{ T element; AVLNode* left; AVLNode* right; int height; AVLNode(const T& theElement,AVLNode* lt,AVLNode* rt,int ht = 0):element(theElement),left(lt),right(rt),height(ht){} }; // class AVLNode AVLNode *root; int Height(AVLNode* t); void insert(const T& x,AVLNode* &t); bool constain(const T& x,AVLNode* t)const; AVLNode* findMin(AVLNode* t)const; AVLNode* findMax(AVLNode* t)const; void makeEmpty(AVLNode* &t); void printTree(AVLNode* t)const; AVLNode* clone(AVLNode *t); void SingleRotateWithLeft(AVLNode* &t); //左子树单旋转 void SingleRotateWithRight(AVLNode* &t); //右子树单旋转 void DoubleRotateWithLeft(AVLNode* &t); //左子树双旋转 void DoubleRotateWithRight(AVLNode* &t); //右子树双旋转 }; //class AVLTree template<class T> int AVLTree<T>::Height(AVLNode *t) { if(t == NULL) return -1; return t->height; } template<class T> void AVLTree<T>::insert(const T& x,AVLNode* &t) { if(t == NULL) t = new AVLNode(x,NULL,NULL); else if(x < t->element) { insert(x,t->left); if(Height(t->left) - Height(t->right) == 2) //失去平衡 { if(x < t->left->element) SingleRotateWithLeft(t); else DoubleRotateWithLeft(t); } } else if(t->element < x) { insert(x,t->right); if(Height(t->right) - Height(t->left) == 2) { if(t->right->element < x) SingleRotateWithRight(t); else DoubleRotateWithRight(t); } } t->height = Max(Height(t->left),Height(t->right)) + 1; } template<class T> bool AVLTree<T>::constain(const T& x,AVLNode* t)const { if(t == NULL) return false; else if(x < t->element) return constain(x,t->left); else if(t->element < x) return constain(x,t->right); else return true; } template<class T> typename AVLTree<T>::AVLNode* AVLTree<T>::findMin(AVLNode *t)const { if(t == NULL) return NULL; else if(t->left != NULL) { return findMin(t->left); } return t; } template<class T> typename AVLTree<T>::AVLNode* AVLTree<T>::findMax(AVLNode *t)const { if(t == NULL) return NULL; else if(t->right != NULL) findMax(t->right); return t; } template<class T> void AVLTree<T>::makeEmpty(AVLNode* &t) { if(t == NULL) return; else { makeEmpty(t->left); makeEmpty(t->right); delete t; } t = NULL; } template<class T> void AVLTree<T>::printTree(AVLNode* t)const { if(t == NULL) return; else { printTree(t->left); std::cout << t->element << std::endl; printTree(t->right); } } template<class T> typename AVLTree<T>::AVLNode* AVLTree<T>::clone(AVLNode *t) { if(t == NULL) return NULL; return new AVLNode(t->element,clone(t->left),clone(t->right)); } template<class T> void AVLTree<T>::SingleRotateWithLeft(AVLNode* &k2) { AVLNode* k1 = k2->left; k2->left = k1->right; k1->right = k2; k2->height = Max(Height(k2->left),Height(k2->right)) + 1; k1->height = Max(Height(k1->left),k2->height) + 1; k2 = k1; } template<class T> void AVLTree<T>::SingleRotateWithRight(AVLNode* &k2) { AVLNode* k1 = k2->right; k2->right = k1 -> left; k1->left = k2; k2->height = Max(Height(k2->left),Height(k2->right)) + 1; k1->height = Max(Height(k1->right),k2->height) + 1; k2 = k1; } template<class T> void AVLTree<T>::DoubleRotateWithLeft(AVLNode* &k2) { SingleRotateWithRight(k2->left); SingleRotateWithLeft(k2); } template<class T> void AVLTree<T>::DoubleRotateWithRight(AVLNode* &k2) { SingleRotateWithLeft(k2->right); SingleRotateWithRight(k2); } #endif //AVLTREE_H 实现部份: #include "AVLTree.h" using namespace std; int main() { AVLTree<int> at; for(int i = 0; i < 300;++i) at.insert(i); at.printTree(); return 0; }