作者:
Phinecos(洞庭散人) 来源:
博客园 发布时间: 2008-08-16 22:39 阅读: 1469 次 推荐: 0
原文链接
[收藏]
#include <stdlib.h>

template<typename T>
class CAVLTree;

template<typename T>
class CAVLTreeNode


{
public:
CAVLTreeNode(const T& item,CAVLTreeNode<T>* lptr = NULL,CAVLTreeNode<T>* rptr = NULL,int balfac=0):data(item),left(lptr),right(rptr),balanceFactor(balfac)

{
}
CAVLTreeNode<T>* Left(void)const

{
return left;
}
CAVLTreeNode<T>* Right(void)const

{
return right;
}
int GetBalanceFactor()const

{
return this->balanceFactor;
}
friend class CAVLTree<T>;
public:
T data;//数据
private:
CAVLTreeNode<T>* left;//左子树
CAVLTreeNode<T>* right;//右子树
int balanceFactor;//平衡因子
CAVLTreeNode<T>* & Left(void)

{
return left;
}
CAVLTreeNode<T>* & Right(void)

{
return right;
}

};

const int LEFTHEAVY = -1;
const int BALANCE = 0;
const int RIGHTHEAVY = 1;

template<typename T>
class CAVLTree


{
public:
CAVLTree(void);
CAVLTree(const CAVLTree<T>& tree);
CAVLTree& operator = (const CAVLTree& rhs);
void Insert(const T& item);
void ClearTree();//清空树
bool Contains(const T& item);//是否包含数据
CAVLTreeNode<T>* FindNode(const T& item,CAVLTreeNode<T>* &parent)const;//寻找节点
CAVLTreeNode<T>* FindMin()const;//找最小值
CAVLTreeNode<T>* FindMax()const;//找最大值
void PrintTree();//前序遍历树(非递归)
virtual ~CAVLTree(void);

protected:
CAVLTreeNode<T>* GetAVLTreeNode(const T& item,CAVLTreeNode<T> *lptr=NULL,CAVLTreeNode<T> *rptr=NULL);
CAVLTreeNode<T>* CopyTree(CAVLTreeNode<T>* t);//拷贝树
void FreeTreeNode(CAVLTreeNode<T>* p);//释放树节点
void DeleteTree(CAVLTreeNode<T>* t);//删除树

//旋转
void SingleRotateLeft(CAVLTreeNode<T> * &p);
void SingleRotateRight(CAVLTreeNode<T> *&p);
void DoubleRotateLeft(CAVLTreeNode<T> *&p);
void DoubleRotateRight(CAVLTreeNode<T> *&p);

void UpdateLeftTree(CAVLTreeNode<T>* &tree,int &reviseBalanceFactor);
void UpdateRightTree(CAVLTreeNode<T>* &tree,int &reviseBalanceFactor);
void AVLInsert(CAVLTreeNode<T> * &tree,CAVLTreeNode<T> *newnode,int &reviseBalanceFactor);

private:
CAVLTreeNode<T> *root;//平衡二叉树树根
int size;//树节点个数
};

平衡二叉树实现代码
#include "BinSTree.h"
#include <iostream>
#include <stack>
using namespace std;


/**//**//**///////////////////////////////////////////////////////////////////////
// Construction/Destruction

/**//**//**///////////////////////////////////////////////////////////////////////
template<typename T>
CAVLTree<T>::CAVLTree()


{
this->root = NULL;
this->size = 0;
}
template<typename T>
CAVLTree<T>::CAVLTree(const CAVLTree<T>& tree)


{
root = this->CopyTree(tree.root);
this->size = tree.size;
}
template<typename T>
CAVLTree<T>::~CAVLTree()


{
this->ClearTree();
}
template<typename T>
CAVLTree<T>& CAVLTree<T>::operator = (const CAVLTree<T>& rhs)


{
if(this==&rhs)
return *this;
this->ClearTree();
root = this->CopyTree(rhs.root);
size = rhs.size;
return *this;
}
template<typename T>
CAVLTreeNode<T>* CAVLTree<T>::GetAVLTreeNode(const T& item,CAVLTreeNode<T>* lptr,CAVLTreeNode<T>* rptr)


{
CAVLTreeNode<T>* p;
p = new CAVLTreeNode<T>(item,lptr,rptr);
if(p==NULL)

{
cerr<<"分配内存失败!"<<endl;
exit(1);
}
return p;
}
template<typename T>
CAVLTreeNode<T>* CAVLTree<T>::FindMin()const


{
CAVLTreeNode<T> *t = root;
while(t->left!=NULL)

{
t = t->left;
}
return t;
}
template<typename T>
CAVLTreeNode<T>* CAVLTree<T>::FindMax()const


{
CAVLTreeNode<T> *t = root;
while(t->right!=NULL)

{
t = t->right;
}
return t;
}
template<typename T>
bool CAVLTree<T>::Contains(const T& item)


{
CAVLTreeNode<T> *p;
return (this->FindNode(item,p)!=NULL);
}

template<typename T>
CAVLTreeNode<T>* CAVLTree<T>::CopyTree(CAVLTreeNode<T>* t)


{
CAVLTreeNode<T> *newnode,*newlptr,*newrptr;
if(t==NULL)
return NULL;
if(t->Left()!=NULL)
newlptr = CopyTree(t->Left());
else
newlptr = NULL;
if(t->Right()!=NULL)
newrptr = CopyTree(t->Right());
else
newrptr = NULL;
newnode = this->GetAVLTreeNode(t->data,newlptr,newrptr);
return newnode;
}
template<typename T>
void CAVLTree<T>::FreeTreeNode(CAVLTreeNode<T>* p)


{
delete p;
p = NULL;
}
template<typename T>
void CAVLTree<T>::DeleteTree(CAVLTreeNode<T>* t)


{
if(t!=NULL)

{
DeleteTree(t->Left());
DeleteTree(t->Right());
FreeTreeNode(t);
}
}
template<typename T>
void CAVLTree<T>::ClearTree()


{
DeleteTree(root);
root = NULL;
}
template<typename T>
CAVLTreeNode<T>* CAVLTree<T>::FindNode(const T& item,CAVLTreeNode<T>* &parent)const


{
CAVLTreeNode<T> *t = root;
parent = NULL;
while(t!=NULL)

{
if(item==t->data)
break;
else

{
parent = t;
if(item<t->data)
t = t->Left();
else
t = t->Right();
}
}
return t;
}
template<typename T>
void CAVLTree<T>::Insert(const T& item)


{
CAVLTreeNode<T>* t = root,*parent = NULL,*newnode;
int reviseBalanceFactor = 0;
newnode = this->GetAVLTreeNode(item);
this->AVLInsert(t,newnode,reviseBalanceFactor);
root = t;
size++;
}
template<typename T>
void CAVLTree<T>::AVLInsert(CAVLTreeNode<T> * &tree,CAVLTreeNode<T> *newnode,int &reviseBalanceFactor)


{

int rebalanceCurrNode;
if (tree==NULL)

{
tree = newnode;
tree->balanceFactor = BALANCE;
reviseBalanceFactor = 1;
}
else if(newnode->data<tree->data)

{
this->AVLInsert(tree->Left(),newnode,rebalanceCurrNode);
if (rebalanceCurrNode)

{
if (tree->balanceFactor==LEFTHEAVY)

{
this->UpdateLeftTree(tree,reviseBalanceFactor);
}
else if (tree->balanceFactor==BALANCE)

{
tree->balanceFactor = LEFTHEAVY;
reviseBalanceFactor = 1;
}
else

{
tree->balanceFactor = BALANCE;
reviseBalanceFactor = 0;
}
}
}
else

{
this->AVLInsert(tree->Right(),newnode,rebalanceCurrNode);
if (rebalanceCurrNode)

{
if (tree->balanceFactor==LEFTHEAVY)

{
tree->balanceFactor = BALANCE;
reviseBalanceFactor = 0;
}
else if (tree->balanceFactor==BALANCE)

{
tree->balanceFactor = RIGHTHEAVY;
reviseBalanceFactor = 1;
}
else
this->UpdateRightTree(tree,reviseBalanceFactor);
}
else
reviseBalanceFactor = 0;
}
}

template<typename T>
void CAVLTree<T>::PrintTree()


{
stack<CAVLTreeNode<T>* > s;
CAVLTreeNode<T>* p = root;
while (p!=NULL || !s.empty())

{
while (p!=NULL) //遍历左子树

{
cout<<p->data<<endl;
s.push(p);
p=p->Left();
}//endwhile

if (!s.empty())

{
p=s.top();
s.pop();
p=p->Right(); //通过下一次循环实现右子树遍历
}//endif
}
}
template<typename T>
void CAVLTree<T>::UpdateLeftTree(CAVLTreeNode<T> *&tree, int &reviseBalanceFactor)


{
CAVLTreeNode<T> *lc;
lc = tree->Left();
if (lc->balanceFactor==LEFTHEAVY)

{
this->SingleRotateRight(tree);
reviseBalanceFactor = 0;
}
else if (lc->balanceFactor==RIGHTHEAVY)

{
this->DoubleRotateRight(tree);
reviseBalanceFactor = 0;
}
}
template<typename T>
void CAVLTree<T>::SingleRotateRight(CAVLTreeNode<T> *&p)


{
CAVLTreeNode<T> *lc;
lc = p->Left();
p->balanceFactor = BALANCE;
lc->balanceFactor = BALANCE;
p->left = lc->Right();
lc->right = p;
p = lc;
}
template<typename T>
void CAVLTree<T>::DoubleRotateRight(CAVLTreeNode<T> *&p)


{
CAVLTreeNode<T> *lc,*np;
lc = p->Left();
np = lc->Right();
if(np->balanceFactor==RIGHTHEAVY)

{
p->balanceFactor = BALANCE;
lc->balanceFactor = RIGHTHEAVY;
}
else if (np->balanceFactor==BALANCE)

{
p->balanceFactor = BALANCE;
lc->balanceFactor = BALANCE;
}
else

{
p->balanceFactor = RIGHTHEAVY;
lc->balanceFactor = BALANCE;
}
np->balanceFactor = BALANCE;
lc->right = np->Left();
np->left = lc;
p->left= np->Right();
np->right = p;
p = np;
}
template<typename T>
void CAVLTree<T>::SingleRotateLeft(CAVLTreeNode<T> *&p)


{
CAVLTreeNode<T> *rc = p->right;

p->balanceFactor = BALANCE;
rc->balanceFactor = BALANCE;

p->right = rc->left;
rc->left = p;
p = rc;

}
template<typename T>
void CAVLTree<T>::DoubleRotateLeft(CAVLTreeNode<T> *&p)


{
CAVLTreeNode<T> *rc, *np;

rc = p->right;
np = rc->left;
if (np->balanceFactor == LEFTHEAVY)

{
p->balanceFactor = BALANCE;
rc->balanceFactor = LEFTHEAVY;
}
else if (np->balanceFactor == BALANCE)

{
p->balanceFactor = BALANCE;
rc->balanceFactor = BALANCE;
}
else

{
p->balanceFactor = LEFTHEAVY;
rc->balanceFactor = BALANCE;
}
np->balanceFactor = BALANCE;
rc->left = np->right;
np->right = rc;
p->right = np->left;
np->left = p;
p = np;
}
template<typename T>
void CAVLTree<T>::UpdateRightTree(CAVLTreeNode<T> *&tree, int &reviseBalanceFactor)


{
CAVLTreeNode<T> *rc = tree->right;

if (rc->balanceFactor == RIGHTHEAVY)

{
SingleRotateLeft(tree);
reviseBalanceFactor = false;
}
else if (rc->balanceFactor == LEFTHEAVY)

{
DoubleRotateLeft(tree);
reviseBalanceFactor = false;
}
}

测试代码
#include "BinSTree.cpp"
#include <iostream>
using namespace std;

CAVLTree<int>* MakeSampleTree()


{//示例AVL树
CAVLTree<int> *tree1 = new CAVLTree<int>();
int a = 5;
tree1->Insert(a);
tree1->Insert(30);
tree1->Insert(65);
tree1->Insert(25);
tree1->Insert(35);
tree1->Insert(50);
tree1->Insert(10);
tree1->Insert(28);
tree1->Insert(26);
tree1->Insert(33);
return tree1;
}

int main(int argc, char* argv[])


{
CAVLTree<int> *tree1 = MakeSampleTree();
tree1->PrintTree();

cout<<tree1->Contains(40)<<endl;
CAVLTreeNode<int> *p = tree1->FindMin();
cout<<p->data<<endl;
system("pause");
return 0;
}