在上篇博文中的二叉搜索树的基础上(无实际联系,只是当时开发的时候参考),实现了AVL平衡树,完美地实现了其中较为困难的旋转操作。使用请注明出处,谢谢。
源代码如下:
#pragma once
//#include "STree.h"
template <class T> class AVLTree;
template<class T, class Ref=T&, class Ptr=T*> class AVLTree_iterator;
template<class T, class Ref=T&, class Ptr=T*> class AVLTree_const_iterator;
template <class T>
class AVLNode {
friend class AVLTree<T>;
friend class AVLTree_iterator<T>;
friend class AVLTree_const_iterator<T>;
protected:
T data;
AVLNode<T> *left, *right, *parent;
int factor;//factor=height(right subtree)-height(left subtree)
void copy(const AVLNode<T> &rhs) {
//if(rhs==NULL) {cout<<"error: no source"<<endl; return;}
left=rhs.left;
right=rhs.right;
parent=rhs.parent;
data=rhs.data;
factor=rhs.factor;
}
public:
AVLNode() {
left=NULL, right=NULL, parent=NULL;
factor=0;
}
AVLNode(const T &item, AVLNode<T> *lptr=NULL, AVLNode<T> *rptr=NULL, AVLNode<T> *pptr=NULL, int ftor=0 )
:data(item), left(lptr), right(rptr), parent(pptr), factor(ftor) {}
~AVLNode() {}
AVLNode(const AVLNode<T> &rhs) { copy(rhs); }
AVLNode &operator=(const AVLNode<T> &rhs) { copy(rhs); return *this; }
int Factor() { return factor; }
};
template <class T>
class AVLTree {
enum {AVLL=-1, AVLB=0, AVLR=1 };// Balance state information stored in each node in AVL tree.
friend class AVLTree_iterator<T>;
friend class AVLTree_const_iterator<T>;
protected:
AVLNode<T> *root;
int size;
AVLNode<T> *GetNode(const T &item, AVLNode<T> *lptr, AVLNode<T> *rptr, AVLNode<T> *pptr, int ftor=0) {
AVLNode<T> *newnode=new AVLNode<T>(item, lptr, rptr, pptr, ftor);
if( newnode==NULL ) {cerr<<"allocate storage for new node failed!"<<endl; exit(0);}
return newnode;
}
AVLNode<T> *copy(AVLNode<T> *rhs) {
AVLNode<T> *lptr=NULL, *rptr=NULL, newnode=NULL;
int ftor=0;
if(rhs==NULL) return NULL;
lptr=copy(rhs->left);
rptr=copy(rhs->right);
newnode=GetNode(rhs->data, lptr, rptr, NULL, rhs->factor);
if(lptr!=NULL) lptr->parent=newnode;
if(rptr!=NULL) rptr->parent=newnode;
return newnode;
}
void DelTree(AVLNode<T> *_root) {
if(_root==NULL) return;
DelTree(_root->left);
DelTree(_root->right);
delete _root;
}
AVLNode<T> *findNode(const T& item) const {//only the type of its return value is different
//with its base class, polymorphism can not be realized
AVLNode<T> *cur=root;
while(cur!=NULL) {
if(cur->data==item) return cur;
else if(cur->data<item) cur=cur->right;
else cur=cur->left;
}
return cur;
}
void SingleRotateRight(AVLNode<T> * &cur) {
AVLNode<T> *leftchild=cur->left;
AVLNode<T> *par=cur->parent;
//after the adjustment, all the nodes will be balanced
leftchild->factor=AVLB;
cur->factor=AVLB;
cur->left=leftchild->right; //the original right subtree of the the leftchild will move to the left subtree of its original parent
if(cur->left!=NULL) cur->left->parent=cur;
leftchild->right=cur; //the new right subtree of the new root should be its original parent
cur->parent=leftchild;
leftchild->parent=par;
cur=leftchild; //leftchild now is the new root
}
void DoubleRotateRight(AVLNode<T> * &cur) {
AVLNode<T> *leftchild=cur->left;
AVLNode<T> *lc_rht_chd=leftchild->right;
AVLNode<T> *par=cur->parent;
//after the adjustment, the balance factor should like this
if(lc_rht_chd->factor==AVLR) {
cur->factor=AVLB;
leftchild->factor=AVLL;
}
else if(lc_rht_chd->factor==AVLB) {
cur->factor=AVLB;
leftchild->factor=AVLB;
}
else {
cur->factor=AVLR;
leftchild->factor=AVLB;
}