AVL树是一种高度平衡树,对于每一个节点,其左子树的高度与右子树的高度相差之多为1。
AVL树是比红黑树更加平衡的树(红黑树中左右子树高度之比小于2)。
AVL树除了平衡性较好外,与普通的二叉查找树没什么大的区别。所以AVL树的代码实现可以基于前面的二叉树实现代码算法导论第十二章——二叉查找树的C++代码实现来实现。实现AVL树的关键在于维持树的平衡性。所以每插入一个节点或删除都有可能要对树进行翻转,以满足平衡性。翻转使用的方法是红黑树中提到的左旋和右旋。根据出现的不同情况对树进行旋转。
虽然思路很清晰,但是实现起来比较麻烦。需要如下步骤:
1、在进行插入节点或删除节点之后,首先要找到树中最大高度节点和最小高度节点:Lnode,Snode
2、然后找到Lnode和Snode的最近共同祖先。
3、根据最近共同祖先和两个节点的位置我们可以分为四种情况进行旋转处理。
情况一:Lnode在ans的右孩子的左侧,则右孩子(12)右旋,ans(6)左旋。
情况2:Lnode在ans右孩子的右侧则ans左旋。
情况三:,Lnode为ans左孩子左侧,ans左孩子(6)右旋,祖先右旋
纠错:节点4应该有一个右孩子
情况四:ans右旋
纠错:12节点应该有一个左孩子。
具体实现代码如下:
BinTreeNode.h
#include<iostream>
using namespace std;
class BinTree;
class BinTreeNode
{
private:
friend BinTree;
int key;
//添加节点高度记录
int height;
BinTreeNode* left;
BinTreeNode* right;
BinTreeNode* parent;
public:
BinTreeNode():key(-1),height(0),left(NULL),right(NULL),parent(NULL){}
BinTreeNode(BinTreeNode* node):key(node->key),height(node->height),left(node->left),right(node->right),parent(node->parent)
{}
BinTreeNode(int num):left(NULL),right(NULL),key(num){}
~BinTreeNode()
{}
int Getkey()
{
return key;
}
BinTreeNode* GetLeft()
{
return this->left;
}
BinTreeNode* Getright()
{
return this->right;
}
void Inorder()
{
if(this!=NULL)
{
this->left->Inorder();
cout<<this->key<<" ";
this->right->Inorder();
}
}
void Preorder()
{
if(this!=NULL)
{
cout<<this->key<<" ";
this->left->Preorder();
this->right->Preorder();
}
}
void Postorder()
{
if(this!=NULL)
{
this->left->Postorder();
this->right->Postorder();
cout<<this->key<<" ";
}
}
void MakeEmpty()
{
if(this!=NULL)
{
this->left->MakeEmpty();
this->right->MakeEmpty();
delete this;
}
}
int GetHeight()
{
int L,R;
if(this==NULL)
{
return 0;
}
L=this->left->GetHeight();
R=this->right->GetHeight();
return 1+(L>R? L:R);
}
};
BinTree.h
#include"BinTreeNode.h"
#include<string>
#include<bitset>
#include<queue>
class BinTree
{
private:
BinTreeNode* root;
//记录具有最大高度的节点
BinTreeNode* Lnode;
//记录具有最小高度的节点
BinTreeNode* Snode;
public:
BinTree():root(NULL),Lnode(NULL),Snode(NULL){}
// BinTree(BinTreeNode* node):root(node){}
~BinTree()
{
MakeEmpty();
Lnode=NULL;
Snode=NULL;
}
void MakeEmpty()
{
BinTreeNode *p=root;
p->MakeEmpty();
}
int Getkey(BinTreeNode* node)
{
return node->Getkey();
}
BinTreeNode* Getroot()
{
return root;
}
int GetHeight(BinTreeNode*node)
{
return node->height;
}
void Inorder()
{
return root->Inorder();
}
void Preorder()
{
return root->Preorder();
}
void Posetorder()
{
return root->Postorder();
}
//调整