最近在看《数据结构与算法》,边学边实现一下里面的数据结构,之前实现了一个比较简单的二叉搜索树,平均搜索速度为O(logN),看起来很快,但是很多时候是达不到这个速度的,因为他会经常构造出深度比较大的树,搜索的时候就很麻烦,然后后面就提到了AVL树,这个同样也是一个二叉搜索树,但是这个二叉树会通过左旋和右旋来平衡二叉搜索树,使其保持两边高度尽量平衡的状态,搜索起来就比较快了,下面是具体的实现
#include <iostream>
using namespace std;
//节点的定义
struct Node
{
int value,Height;
Node* left,*right;
Node()
{
left=right=NULL;
value=Height=0;
}
};
//定义高度函数,返回高度并且处理指针为NULL的情况
static inline int Height(Node* n)
{
if(n==NULL)
return -1;
else
return n->Height;
}
//查找函数,找到特定的值,返回节点的指针
Node* Find(int x,Node* n)
{
if(n==NULL)
return NULL;
if(x==n->value)
return n;
else if(x>n->value)
return Find(x,n->right);
else
return Find(x,n->left);
}
//单旋转,左旋
Node* SingleRotateWithLeft(Node*& n)
{
Node * k1=n->left;
n->left=k1->right;
k1->right=n;
return k1;
}
//双旋转,左旋
Node* DoubleRotateWithLeft(Node*& k3)
{
Node* k1=k3->left;
Node* k2=k1->right;
k1->right=k2->left;
k3->left=k2->right;
k2->left=k1;
k2->right=k3;
return k2;
}
//单旋转,右旋
Node* SingleRotateWithRight(Node*& k2)
{
Node* k1=k2->right;
k2->right=k1->left;
k1->left=k2;
return k1;
}
//双旋转,右旋
Node* DoubleRotateWithRight(Node*& k3)
{
Node* k1=k3->right;
Node* k2=k1->left;
k3->right=k2->left;
k1->left=k2->right;
k2->left=k3;
k2->right=k1;
return k2;
}
//插入,找到相同值的话不插入
Node* Insert(int x,Node*& n)
{
if(n==NULL)//找到位置插入
{
n=new Node;
n->value=x;
n->Height=0;
return n;
}
else
{
if(x<n->value)
{
n->left=Insert(x,n->left);
if(Height(n->left)-Height(n->right)==2)
{
if(x<n->left->value)
{
n=SingleRotateWithLeft(n);
}
else
{
n=DoubleRotateWithLeft(n);
}
}
}
else if(x>n->value)
{
n->right=Insert(x,n->right);
if(Height(n->right)-Height(n->left)==2)
{
if(x>n->right->value)
{
n=SingleRotateWithRight(n);
}
else
{
n=DoubleRotateWithRight(n);
}
}
}
}
n->Height=max(Height(n->left),Height(n->right))+1;//调整高度
return n;
}
//输出树
void printTree(Node* n)
{
if(n->left!=NULL)
printTree(n->left);
cout<<n->value<<" ";
if(n->right!=NULL)
printTree(n->right);
}
//删除树
void DeleteTree(Node* n)
{
if(n->left!=NULL)
DeleteTree(n->left);
if(n->right!=NULL)
DeleteTree(n->right);
delete n;
}
int main()
{
Node* no=NULL;
for(int i=1;i<10;i++)
Insert(i,no);
printTree(no);
cout<<endl;
DeleteTree(no);
return 0;
}