最近在自学AVL树,感觉在实现树的生成,和一些基本功能上还有些技巧,自己也写了一个。希望和大家一起来讨论一下,是程序的功能更全面些,代码更简洁些。代码如下:
#include"iostream.h"
struct node{
int data;//数据域
node*left;//左孩子指针
node*right;//右孩子指针
int height;//高度 这里用高度来表示树的平衡情况(用平衡因子也行 不过自己感觉不太直观,调整起来也麻烦)
};
class AVLtree{
public:
node* root;//树的根结点
AVLtree(){root=NULL;}//根结点初始化为空
int max(int a,int b);//比较大小函数
int high(node*p);//得到p子树的高度
void creat();//创建AVL树
void turnleft(node*&t);//单向左旋转
void turnright(node*&t);//单向右旋转
void doubleleft(node*&t);//双向左旋转
void doubleright(node*&t);//双向右旋转
void insert(node*&t,int x);//插入函数
void preonder(node*t);//前序遍历
void show1();//前序遍历
};
int AVLtree::max(int a,int b){
if(a>b) return a;
return b;
}
int AVLtree::high(node*p){
if(p==NULL) return 0;
return max(high(p->left),high(p->right))+1;
}
void AVLtree::turnleft(node*&t){
node*p=t->right;
t->right=p->left;
p->left=t;
t->height=max(high(t->left),high(t->right))+1;
p->height=max(t->height,high(p->right))+1;
t=p;
}
void AVLtree::turnright(node*&t){
node*p=t->left;
t->left=p->right;
p->right=t;
t->height=max(high(t->left),high(t->right))+1;
p->height=max(high(p->left),t->height)+1;
t=p;
}
void AVLtree::doubleleft(node*&t){
node*p=t->right;
turnright(p);
turnleft(t);
}
void AVLtree::doubleright(node*&t){
node*p=t->left;
turnleft(p);
turnright(t);
}
void AVLtree::insert(node*&t,int x){
node*p=new node;// 创建新结点作为插入结点
p->data=x;
p->height=1;//因为AVL树为二叉搜索树 因此插入的新结点 一定会先插入在空结点
p->left=NULL;
p->right=NULL;
if(t==NULL){//如果t为空则插入 t=p ;
t=p;
return;//返回流程
}
else{//如不是则分两种情况
if(t->data>x){
insert(t->left,x);//插入的两种情况 1 插入左孩子的子树
if(high(t->left)-high(t->right)==2){// 如果这里直接写(t->left->height-t->right->height==2)会出错,想想问什么?
if(t->left->data>x)//若插入到 左孩子的左子树 进行单向右旋转
turnright(t);
else doubleright(t);//反之 进行双向右旋转
}
}
if(t->data<x){//情况2 插入右孩子的子树
insert(t->right,x);
if(high(t->right)-high(t->left)==2){
if(t->right->data<x)
turnleft(t);//若插入到右孩子的有字数进行单向左旋转
else doubleleft(t);//反之进行双向左旋转
}
}
}
t->height=max(high(t->left),high(t->right))+1;//插入,旋转 完成后,修改t的高度
}
void AVLtree::preonder(node*t){
if(t==NULL) return ;
else{
cout<<t->data<<' ';
preonder(t->left);
preonder(t->right);
}
}
void AVLtree::show1(){
preonder(root);
}
void AVLtree::creat()
{
cout<<"if your input 0,it will stop creat the AVLtree:"<<endl;//输入0则生成树函数 结束
int n;
while(cin>>n&&n!=0)
insert(root,n);
}
void main(){
AVLtree b;
b.creat();
b.show1();
}