一颗AVL树是其每个节点的左子树和右子树的高度做多差1的二叉查找树。下面几种几种情况需要进行调整满足AVL树的性质。
1.在K3节点左子树或右子树进行一次插入,如下图1,导致了K1节点出现高度不平衡,此时采用右单旋调整:具体做法,抓住K2节点,使劲的摇动它,在重力的作用下,K2变成新的根,二叉查找树性质告诉我们,在原树中K1>K2,于是在新树中K1变成K2的右儿子,K3和A仍然为K2的左儿子和K1的右儿子,子树B包含在K2和K1之间,可以将其放在K1的左儿子位置。调整后如图1.2。
图1.1 图1.2
2.左单旋,其做法和1的类似,这里就直接给出旋转的结果。未调整前如图2.1,调整后如图2.2。
图2.1 图2.2
3.左—右双旋。先在K2和K3之间进行左旋,再在K3和K1之间进行右旋。便可达到树平衡的效果。如下图3.1、3.2、3.3.
图3.1 图3.2(图3.1 K2和K3节点间的左旋) 图3.3(图3.2 K3和K1节点间的右旋)
4.右—左旋转,如下图4.1、4.2、4.3。
图4.1 图4.2(图4.1 K2和K3节点间的右旋) 图4.3(图4.2 K1和K3节点间的左旋)
实现AVL树的代码如下:
avltree.h
#pragma once
template<typename Comparable>
struct Node
{
Comparable element;
Node* left;
Node* right;
int height;
Node(Comparable e,Node* l,Node* r,int h):element(e),left(l),right(r),height(h){}
};
enum MODE
{
PRE,
MID,
POST
};
template<typename Comparable>
class Avltree
{
public:
Avltree();
Avltree(Avltree& rh);
bool contains(Comparable x);//判断是否包含某一个元素
Comparable findmin(); //查找树中最小的元素
Comparable findmax(); //查找树中最大的元素
void insert(Comparable x); //插入元素
void remove(Comparable x); //删除指定的元素
void print(MODE mode); //输出树的全部元素
private:
Node<Comparable>* root;
bool contains(Comparable x,Node<Comparable>* t);//判断是否包含某一个元素
Node<Comparable>* findmin(Node<Comparable>* t);//查找树中最小的元素
Node<Comparable>* findmax(Node<Comparable>* t);//查找树中最大的元素
int Height(Node<Comparable>* t); //计算某个节点的高度
int max(int a,int b); //比较两个元素的,返回最大值
void insert(Comparable x,Node<Comparable>* &t);//插入元素
void remove(Comparable x,Node<Comparable>* &t);//删除指定的元素
Node<Comparable>* singleRotateRight(Node<Comparable>* &t);//右单旋转
Node<Comparable>* doubleRotateLeft(Node<Comparable>* &t);//左—右双旋转
Node<Comparable>* singleRotateLeft(Node<Comparable>* &t);//左单旋转
Node<Comparable>* doubleRotateRight(Node<Comparable>* &t);//右—左双旋转
void PrePrint(Node<Comparable>* t); //前序遍历输出
void MidPrint(Node<Comparable>* t); //中序遍历输出
void PostPrint(Node<Comparable>* t); //后序遍历输出
};
avltree.cpp
#include "stdafx.h"
#include"avltree.h"
#include<iostream>
using namespace std;
template<typename Comparable>
Avltree<Comparable>::Avltree()
{
root=NULL;
}
template<typename Comparable>
Avltree<Comparable>::Avltree(Avltree& rh)
{
root=rh.root;
}
template<typename Comparable>
bool Avltree<Comparable>::contains(Comparable x)//判断书否包含某一元素
{
return contains(x,root);
}
template<typename Comparable>
bool Avltree<Comparable>::contains(Comparable x,Node<Comparable>* t)
{
if(t==NULL)
return false;
else if(x==t->element)
return true;
else if(x<t->element)
contains(x,t->left);
else
contains(x,t->right);
}
template<typename Comparable>
Comparable Avltree<Comparable>::findmin()//查找最小元素
{
return findmin(root)->left->element;
}
template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::findmin(Node<Comparable>* t)
{
if(t==NULL)
return NULL;
else if(t->left->left==NULL)
return t;
else
findmin(t->left);
}
template<typename Comparable>
Comparable Avltree<Comparable>::findmax()//查找最大元素
{
return findmax(root)->right->element;
}
template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::findmax(Node<Comparable>* t)
{
if(t==NULL)
return NULL;
else if(t->right->right==NULL)
return t;
else
findmax(t->right);
}
template<typename Comparable>
int Avltree<Comparable>::Height(Node<Comparable>* t)//查找某一节点的高度
{
if(t==NULL)
return -1;
else
return t->height;
}
template<typename Comparable>
int Avltree<Comparable>::max(int a,int b)
{
return a>b?a:b;
}
template<typename Comparable>
void Avltree<Comparable>::insert(Comparable x)//插入元素
{
insert(x,root);
}
template<typename Comparable>
void Avltree<Comparable>::insert(Comparable x,Node<Comparable>* &t)
{
if(t==NULL)
t=new Node<Comparable>(x,NULL,NULL,0);
else if(x<t->element)
{
insert(x,t->left);
if(Height(t->left)-Height(t->right)==2)
if(x<t->left->element)
t=singleRotateLeft(t);
else
t=doubleRotateLeft(t);
}
else
{
insert(x,t->right);
if(Height(t->right)-Height(t->left)==2)
if(x>t->right->element)
t=singleRotateRight(t);
else
t=doubleRotateRight(t);
}
t->height=max(Height(t->left),Height(t->right))+1;
}
template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::singleRotateRight(Node<Comparable>* &t)//右单旋转
{
Node<Comparable>* temp=t->left;
t->left=temp->right;
temp->right=t;
t->height=max(Height(t->left),Height(t->right))+1;
temp->height=max(Height(temp->left),t->height)+1;
return temp;
}
template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::singleRotateLeft(Node<Comparable>* &t)//左单旋转
{
Node<Comparable>* temp=t->right;
t->right=temp->left;
temp->left=t;
t->height=max(Height(t->left),Height(t->right))+1;
temp->height=max(Height(temp->right),t->height)+1;
return temp;
}
template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::doubleRotateLeft(Node<Comparable>* &t)//左—右双旋转
{
t->left=singleRotateLeft(t->left);
return singleRotateRight(t);
}
template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::doubleRotateRight(Node<Comparable>* &t)//右—左双旋转
{
t->right=singleRotateRight(t->right);
return singleRotateLeft(t);
}
template<typename Comparable>
void Avltree<Comparable>::remove(Comparable x)//删除元素
{
remove(x,root);
}
template<typename Comparable>
void Avltree<Comparable>::remove(Comparable x,Node<Comparable>* &t)
{
if(t==NULL)
return;
else if(x<t->element)
{
remove(x,t->left);
if(Height(t->right)-Height(t->left)==2)
{
Node<Comparable>* temp=t->right;
if(Height(temp->right)>=Height(temp->left))
t=singleRotateRight(t);
else
t=doubleRotateRight(t);
}
}
else if(x>t->element)
{
remove(x,t->right);
if(Height(t->left)-Height(t->right)==2)
{
Node<Comparable>* temp=t->left;
if(Height(temp->left)>=Height(temp->right))
t=singleRotateLeft(t);
else
t=doubleRotateLeft(t);
}
}
else if(t->left!=NULL&&t->right!=NULL)
{
Node<Comparable>* temp=findmin(t->right);
Node<Comparable>* OldNode=temp->left;
t->element=OldNode->element;
temp->left=NULL;
delete OldNode;
}
else if(t->left!=NULL)
{
t=t->left;
delete t->left;
}
else if(t->right!=NULL)
{
t=t->right;
delete t->right;
}
else
{
Node<Comparable>* OldNode=t;
t=NULL;
delete OldNode;
}
}
template<typename Comparable>
void Avltree<Comparable>::print(MODE mode)
{
if(mode==PRE)
PrePrint(root);
else if(mode==MID)
MidPrint(root);
else if(mode==POST)
PostPrint(root);
else
return;
cout<<endl;
}
template<typename Comparable>
void Avltree<Comparable>::PrePrint(Node<Comparable>* t)
{
if(t==NULL)
return;
else
{
cout<<t->element<<" ";
PrePrint(t->left);
PrePrint(t->right);
}
}
template<typename Comparable>
void Avltree<Comparable>::MidPrint(Node<Comparable>* t)
{
if(t==NULL)
return;
else
{
MidPrint(t->left);
cout<<t->element<<" ";
MidPrint(t->right);
}
}
template<typename Comparable>
void Avltree<Comparable>::PostPrint(Node<Comparable>* t)
{
if(t==NULL)
return;
else
{
PostPrint(t->left);
PostPrint(t->right);
cout<<t->element<<" ";
}
}
AVL.cpp
// AVL.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include"avltree.h"
#include"avltree.cpp"
#include<iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
Avltree<int> a;
a.insert(3);
a.insert(2);
a.insert(1);
a.insert(4);
a.insert(5);
a.insert(6);
a.insert(7);
a.insert(16);
a.insert(15);
a.insert(14);
a.insert(13);
a.insert(12);
a.insert(11);
a.insert(8);
a.insert(10);
a.insert(9);
a.remove(12);
a.print(MID);
return 0;
}