平衡二叉树定义:平衡二叉树是二叉排序树,其中每个节点的左子树和右子树的高度至多等于1.
平衡二叉树是两位俄罗斯科学家(G.M.Adelson-Velskill and E.M.Landis)与1962年一种解决平衡二叉树的算法所以又叫做AVL树
平衡二叉树的实现原理:在构建二叉排序树的过程中保证每一次的插入节点,首先,寻找做小不平衡子树。在保证二叉排序树特性的情况下,通过旋转最小不平衡子树使之成为新的平衡二叉树。
实现过程,
在每个节点中加入平衡因子。bf 用1,0,-1分别表示左子树的高度减去右子树的高度
如果出现自小不平衡子树时一定是下列清空之一。其中最N表示新节点
AE的操作是对称的可以通过一次旋转得到平衡二叉树。需要调整两个节点的平衡因子。对于BC和FG也是对称的需要经过两次旋转得到AVL树。此时需要调整三个节点的平衡因子。
具体的调节过程如图以ABC为例
具体的代码如下:
#include<iostream>
using namespace std;
typedef struct BiTNode
{
int data;
int bf;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
/*
向右旋转P所指向的二叉树 不调整平衡因子
*/
void R_Rotate(BiTree *P)
{
BiTree L;
L = (*P)->lchild;
(*P)->lchild=L->rchild;
L->rchild=(*P);
*P=L;
}
/*
向左旋转P所指向的二叉树 不调整平衡因子
*/
void L_Rotate(BiTree *P)
{
BiTree R;
R= (*P)->rchild;
(*P)->rchild=R->lchild;
(R->lchild)=(*P);
(*P)=R;
}
const int LH = +1;
const int EH = 0;
const int RH = -1;
/*
如果最小不平衡树T是由于新的节点插入在T的左子树上就进行做做平衡调整
输入参数指向最不平衡子树指针的指针
*/
void LeftBlance(BiTree *T)
{
BiTree L,Lr;
L = (*T)->lchild;
switch(L->bf)
{
case LH:
//插入发生在L的左子树上属于情况A
L->bf=(*T)->bf=EH;
R_Rotate(T);
// cout<<"abc";
break;
case RH:
Lr = L->rchild;
switch (Lr->bf)
{
case LH:
//情况B
Lr->bf=EH;
L->bf=EH;
(*T)->bf=RH;
L_Rotate(&((*T)->lchild));
R_Rotate(T);
break;
case EH:
//该种请款出现在叶子节点上
Lr->bf=EH;
L->bf=EH;
(*T)->bf=EH;
L_Rotate(&((*T)->lchild));
R_Rotate(T);
break;
case RH:
//情况C
Lr->bf=EH;
L->bf=LH;
(*T)->bf=EH;
L_Rotate(&((*T)->lchild));
R_Rotate(T);
break;
}
}
}
/*
如果最小不平衡树T是由于新的节点插入在T的右子树上就进行做做平衡调整
输入参数指向最不平衡子树指针的指针
*/
void RightBalance(BiTree *T)
{
BiTree R,RL;
R = (*T)->rchild;
switch(R->bf)
{
case RH:
(*T)->bf = R->bf = EH;
L_Rotate(T);
break;
case EH:
break;
case LH:
RL = R->lchild;
switch (RL->bf)
{
case EH:
(*T)->bf=RL->bf=R->bf=EH;
R_Rotate(&((*T)->rchild));
L_Rotate(T);
break;
case LH:
RL->bf=EH;
(*T)->bf=EH;
R->bf = RH;
R_Rotate(&((*T)->rchild));
L_Rotate(T);
break;
case RH:
RL->bf=EH;
(*T)->bf=LH;
R->bf = EH;
R_Rotate(&((*T)->rchild));
L_Rotate(T);
break;
}
break;
}
}
void printL(BiTree tree)
{
if(NULL == tree)
return;
cout<<tree->data<< " ";
printL(tree->lchild);
printL(tree->rchild);
}
bool InSertData(BiTree *tree,int *taller,int data)
{
if(NULL==(*tree))
{
*taller =1;
BiTree newnode=(BiTree)malloc(sizeof(BiTNode));
newnode->bf=0;
newnode->lchild=newnode->rchild=NULL;
newnode->data=data;
*tree=newnode;
return true;
}
if((*tree)->data==data)
return false;
if((*tree)->data>data)
{
bool suc = InSertData(&((*tree)->lchild),taller,data);
if(!suc)
return false;
if(1== *taller)
{
switch ((*tree)->bf)
{
case LH:
*taller =0;
LeftBlance(tree);
break;
case EH:
(*tree)->bf=LH;
*taller = 1;
break;
case RH:
(*tree)->bf=EH;
*taller = 0;
break;
}
}
return true;
}
else
{
//将数据插入到右子树上
if(!InSertData(&((*tree)->rchild),taller,data))
return false;
if(1 == *taller)
{
switch((*tree)->bf)
{
case LH:
(*tree)->bf = EH;
*taller = 0;
break;
case EH:
(*tree)->bf = RH;
*taller = 1;
break;
case RH:
RightBalance(tree);
*taller = 0;
break;
}
}
return true;
}
}
int main()
{
int i;
int a[10] = { 3,2,1,4,5,6,7,10,9,8};
// int a[10] = { 4,5,6,7,10,9,8};
BiTree T=NULL;
int taller =0;
for (i =0;i<10;i++)
{
InSertData(&T,&taller,a[i]);
cout<<a[i]<<" ";
printL(T);
cout<<endl;
}
//printL(T);
return 1;
}