AVL需要在BST的基础上进行实现,因此首先需要将BST的常用操作封装在头文件<bstree.h>中。而BST又依赖于二叉树的实现,因此二叉树的实现封装在<bintree.h>中。如下:
<bintree.h>
// 二叉树的头文件
#ifndef bintree_h
#define bintree_h
#include <iostream>
using namespace std;
template<class Elem>
struct BinNode{
Elem data;
int h;
BinNode<Elem>* left;
BinNode<Elem>* right;
BinNode(Elem x){
data=x;
h=0;
left=right=NULL;
}
};
template<class Elem>
class BinTree{
protected:
BinNode<Elem>* root;
void rpreprint(BinNode<Elem>* r);
void rinprint(BinNode<Elem>* r);
void rpostprint(BinNode<Elem>* r);
int cntLeaves(BinNode<Elem>* r);
BinNode<Elem>* rfindX(Elem x,BinNode<Elem>* r);
void rprint(BinNode<Elem>* r,int depth);
public:
BinTree() {root=NULL;}
BinTree(Elem r){
root=new BinNode<Elem>(r);
}
~BinTree(){ };
void preprint(){
rpreprint(root);
cout<<endl;
}
void inprint(){
rinprint(root);
}
void postprint(){
rpostprint(root);
}
void print(){
rprint(root,0);
}
BinNode<Elem>* findX(Elem x){
return rfindX(x,root);
}
bool insert(Elem p,int LorR,Elem x);
int cnt(){
return cntLeaves(root);
}
};
template<class Elem>
void BinTree<Elem>::rpreprint(BinNode<Elem>* r){ // 对于传指针,一定不要掉以轻心,要首先看一下指针是不是空指针
if(r==NULL) return;
cout<<r->data<<" ";
rpreprint(r->left);
rpreprint(r->right);
}
template<class Elem>
void BinTree<Elem>::rinprint(BinNode<Elem>* r){
if(r==NULL) return;
rinprint(r->left);
cout<<r->data<<" ";
rinprint(r->right);
}
template<class Elem>
void BinTree<Elem>::rpostprint(BinNode<Elem>* r){
if(r==NULL) return;
rinprint(r->left);
rinprint(r->right);
cout<<r->data<<" ";
}
template<class Elem>
int BinTree<Elem>::cntLeaves(BinNode<Elem>* r){
if(r==NULL) return 0;
if(r->left==NULL && r->right==NULL) return 1;
return cntLeaves(r->left)+cntLeaves(r->right);
}
template<class Elem>
BinNode<Elem>* BinTree<Elem>::rfindX(Elem x,BinNode<Elem>* r){
if(!r) return NULL;
if(r->data==x) return r;
BinNode<Elem>* found;
found=rfindX(x,r->left);
return found?found:rfindX(x,r->right);
}
template<class Elem>
void BinTree<Elem>::rprint(BinNode<Elem>* r,int depth){
for(int i=0;i<depth;i++) cout<<" ";
if(!r){
cout<<"[/]"<<endl;
}
else{
cout<<r->data<<endl;
rprint(r->left,depth+1);
rprint(r->right,depth+1);
}
}
template<class Elem>
bool BinTree<Elem>::insert(Elem p,int LorR,Elem x){
BinNode<Elem>* found;
found=findX(p);
if(!found) return false;
if(LorR==0){
if(found->left) return false;
found->left=new BinNode<Elem>(x);
}
else{
if(found->right) return false;
found->right=new BinNode<Elem>(x);
}
return true;
}
#endif // bintree_h
<bstree.h>
// bstree.h
#ifndef bstree_h
#define bstree_h
#include <iostream>
#include "bintree.h"
using namespace std;
template<class Elem>
class BSTree : public BinTree<Elem>{
protected:
BinNode<Elem>* rfindMax(BinNode<Elem>* r){
if(r->right==NULL) return r;
return rfindMax(r->right); // βµÝ¹é
}
virtual BinNode<Elem>* rinsert(Elem x,BinNode<Elem>* r){
if(r==NULL){
r=new BinNode<Elem>(x);
if(!r) throw -1;
}
else if(x<r->data) r->left=rinsert(x,r->left);
else if(x>r->data) r->right=rinsert(x,r->right);
else throw -2;
return r;
}
BinNode<Elem>* remove(Elem x,BinNode<Elem>* r){
BinNode<Elem>* tmp;
if(!r) throw -1;
else if(x<r->data){
r->left=remove(x,r->left);
}
else if(x>r->data){
r->right=remove(x,r->right);
}
else{
if(r->left && r->right){
tmp=rfindMax(r->left);
r->data=tmp->data;
r->left=remove(tmp->data,r->left);
}
else{
tmp=r;
r=r->left?r->left:r->right;
delete tmp;
}
}
return r;
}
public:
BSTree(){
this->root=NULL;
}
BinNode<Elem>* findMax(){
// return rfindMax(this->root);
BinNode<Elem>* tmp=this->root;
while(tmp && tmp->right){
tmp=tmp->right;
}
return tmp;
}
BinNode<Elem>* findMin(){
BinNode<Elem>* tmp=this->root;
while(tmp && tmp->left){
tmp=tmp->left;
}
return tmp;
}
BinNode<Elem>* findX(Elem x){
BinNode<Elem>* tmp=this->root;
while(tmp && x!=tmp->data){
if(x<tmp->data) tmp=tmp->left;
else tmp=tmp->right;
}
return tmp;
}
bool insert(Elem x){
try{
this->root=rinsert(x,this->root);
}
catch(int e){
return false;
}
return true;
}
bool remove(Elem x){
try{
this->root=remove(x,this->root);
}
catch(int e){
return false;
}
return true;
}
};
#endif // bstree_h
AVL的实现如下:
#include <iostream>
#include "bstree.h"
using namespace std;
template<class Elem>
class AVLTree : public BSTree<Elem>{
protected:
int height(BinNode<Elem>* r){
if(!r) return -1;
return r->h;
}
BinNode<Elem>* LLrotate(BinNode<Elem>* r){
BinNode<Elem>* child;
child=r->left;
r->left=child->right;
child->right=r;
r->h=max(height(r->left),height(r->right))+1;
child->h=max(height(child->left),height(child->right))+1;
return child;
}
BinNode<Elem>* RRrotate(BinNode<Elem>* r){
// cout<<"RR"<<endl;
BinNode<Elem>* child;
child=r->right;
r->right=child->left;
child->left=r;
r->h=max(height(r->left),height(r->right))+1;
child->h=max(height(child->left),height(child->right))+1;
return child;
}
BinNode<Elem>* LRrotate(BinNode<Elem>* r){
r->left=RRrotate(r->left);
return LLrotate(r);
}
BinNode<Elem>* RLrotate(BinNode<Elem>* r){
r->right=LLrotate(r->right);
return RRrotate(r);
}
BinNode<Elem>* rinsert(Elem x,BinNode<Elem>* r){
if(r==NULL){
r=new BinNode<Elem>(x);
if(!r) throw -1;
}
else if(x<r->data){
r->left=rinsert(x,r->left);
if(height(r->left)-height(r->right)==2){
if(x<r->left->data)
r=LLrotate(r);
else
r=LRrotate(r);
}
}
else if(x>r->data){
r->right=rinsert(x,r->right);
if(height(r->right)-height(r->left)==2){
if(x>r->right->data)
r=RRrotate(r);
else
r=RLrotate(r);
}
}
else throw -2;
r->h=max(height(r->left),height(r->right))+1;
return r;
}
public:
AVLTree(){
this->root=NULL;
}
};
int main(){
AVLTree<int> t;
t.insert(50);
t.insert(30);
t.insert(60);
t.insert(20);
t.insert(35);
t.print();
t.insert
cout<<"-------"<<endl;
t.insert(33);
t.print();
return 0;
}