平衡因子计算:二叉树上左子树深度减去右子树深度的值称为平衡因子BF。也可以看作是左子树高度减去右子树高度。
改进二叉排序树的结点结构,增加一个BF,存储平衡因子:
typedef struct BitNode
{
int data;
int BF;
struct BitNode *left,*right;
}BitNode,*BiTree;
对于右旋操作:
void R_Rotate(BiTree *p)//ÓÒÐýת
{
BiTree L=(*P)->left;
(*p)->left=L->right;
L->right=(*p);
(*p)=L;
}
左旋类似,不再重复。
对于左平衡旋转出力的函数代码:
void leftBalance(BiTree *T)
{
//左平衡旋转的处理
BiTree L,Lr;
L=(*T)->left;
switch(L->BF)
{
case LH://左边高,情况1,直接右旋实现平衡
(*T)->BF=L->BF=EH;
R_Rotate(T);
break;
case RH:
Lr=L->right;
switch(Lr->BF)
{
case LH:
(*T)->BF=RH;//情况2
L->BF=EH;
break;
case EH:
(*T)->BF=EH;//情况3
L->BF=EH;
break;
case RH:
(*T)->BF=EH;//情况4
L->BF=LH;
break;
}
Lr->BF=EH;//旋转平衡后Lr变为根节点;
L_Rotate(&(*T)->left);
R_Rotate(T);
}
}
情况1为连续两次左旋,比较简单,略,2,3,4如下图,画的有些丑,但是能看懂,注意平衡因子的变化。
平衡二叉树的建立:
int InsertAVL(BiTree *T,int e,int *taller)
//taller用来判断树是否长高
{
if(!*T)//如果不存在该节点,创建节点
{
*T=(BiTree)malloc(sizeof(BitNode));
(*T)->data=e;
(*T)->left=(*T)->right=NULL;
(*T)->BF=EH;
*taller=true;
}
else
{
if((*T)->data==e)
{
*taller=false;
return false;
}
if(e<(*T)->data)
{
if(!InsertAVL(&(*T)->left,e,taller))
{
return false;
}
if(taller)
{
case LH:
leftBalance(T);
*taller=false;
break;
case EH:
(*T)->BF=LH;
*taller=true;
break;
case RH:
(*T)->BF=EH;
*taller=false;
break;
}
}
else
{
if(!InsertAVL(&(*T)->right,e,taller))
{
return false;
}
if(taller)
{
case LH:
(*T)->BF=EH;
*taller=false;
break;
case EH:
(*T)->BF=RH;
*taller=true;
break;
case RH:
rightBalance(T);
*taller=false;
break;
}
}
}
return true;
}