重点在于指针的运用
//平衡二叉树又称AVL树
//AVL树性质:左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1
#include <stdio.h>
#include <stdlib.h>
#define LH 1 //左子树高1
#define EH 0 //左、右子树等高
#define RH -1 //右子树高1
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int Boolean;
typedef struct BSTNode
{
int data;
int bf;
struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
int EQ(int a,int b);
int LT(int a,int b);
void R_Rotate(BSTree *T);
void L_Rotate(BSTree *T);
void LeftBalance(BSTree *T);
void RightBalance(BSTree *T);
Status InsertAVL(BSTree *T,int e,Boolean *taller);
int main()
{
BSTree *T;
T=(BSTree *)malloc(sizeof(BSTree));
*T=NULL;
int e;
Boolean *taller;
taller=(int *)malloc(sizeof(int));
printf("请输入要插入的数--输入0退出:");
scanf("%d",&e);
while(e)
{
InsertAVL(T,e,taller);
printf("请输入要插入的数--输入0退出:");
scanf("%d",&e);
}
return 0;
}
//若在平衡的二叉排序树T中不存在和e有相同关键字的结点,则插入一个数据元素为e的新结点
//并返回1,否则返回0.若因插入而使二叉排序树失去平衡,则作平衡旋转处理
//布尔变量taller反映T长高与否
Status InsertAVL(BSTree *T,int e,Boolean *taller)
{
if(!(*T)) //如果是空树,则分配空间,生成根结点
{
BSTree p;
p=(BSTree )malloc(sizeof(BSTNode));
p->data=e;
p->lchild=p->rchild=NULL;
p->bf=EH;
*taller=TRUE;
*T=p;
}
else
{
if(EQ(e,(*T)->data))
{
*taller=FALSE;
return 0;
}
if(LT(e,(*T)->data)) //如果小于当前结点,则插入左子树
{
if(!InsertAVL(&(*T)->lchild,e,taller))
return 0; //如果左子树插入失败,则结束,如果插入成功,则往下继续
if(*taller)
switch((*T)->bf)
{
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)->rchild,e,taller))
return 0;
if(*taller)
switch((*T)->bf)
{
case LH:
(*T)->bf=EH;
*taller=FALSE;
break;
case EH:
(*T)->bf=RH;
*taller=TRUE;
break;
case RH:
RightBalance(T);
*taller=FALSE;
break;
}
}
}
return 1;
}
//由于在T的左子树根结点的左子树上插入结点,使T的平衡因子由1增至2而失去平衡
//则需进行一次右旋
void R_Rotate(BSTree *T)
{
BSTNode *lc;
lc=(BSTNode *)malloc(sizeof(BSTNode));
lc=(*T)->lchild;
(*T)->lchild=lc->rchild;
lc->rchild=(*T);
(*T)=lc;
}
//由于在T的右子树根结点的右子树上插入结点,使T的平衡因子由-1增至-2而失去平衡
//则需进行一次左旋
void L_Rotate(BSTree *T)
{
BSTNode *rc;
rc=(BSTNode *)malloc(sizeof(BSTNode));
rc=(*T)->rchild;
(*T)->rchild=rc->lchild;
rc->lchild=(*T);
(*T)=rc;
}
void LeftBalance(BSTree *T)
{
BSTNode *lc,*rd;
lc=(BSTNode *)malloc(sizeof(BSTNode));
rd=(BSTNode *)malloc(sizeof(BSTNode));
lc=(*T)->lchild;
switch(lc->bf)
{
case LH: //如果左子树是左高,则一定是插入在左子树的左子树才会导致失衡
(*T)->bf=lc->bf=EH;
R_Rotate(T); //因此需要进行右旋
break;
case RH: //如果左子树是右高,则一定是插入在左子树的右子树才会导致失衡
rd=lc->rchild; //左子树的右子树
switch(rd->bf)
{
case LH: //如果左子树的右子树是左高,则是插入在左子树的右子树的左子树
(*T)->bf=RH; //则旋转后,根结点将会是右高
lc->bf=EH; //左子树结点将会是等高
break;
case EH: //如果是等高,则
(*T)->bf=lc->bf=EH;
break;
case RH:
(*T)->bf=EH;
lc->bf=LH;
break;
}
rd->bf=EH;
L_Rotate(&(*T)->lchild);
R_Rotate(T);
}
}
void RightBalance(BSTree *T)
{
BSTNode *rc,*rd;
rc=(BSTNode *)malloc(sizeof(BSTNode));
rd=(BSTNode *)malloc(sizeof(BSTNode));
rc=(*T)->rchild;
switch(rc->bf)
{
case RH: //如果右子树是右高,则一定是插入在右子树的右子树才会导致失衡
(*T)->bf=rc->bf=EH;
L_Rotate(T); //因此需要进行左旋
break;
case LH: //如果右子树是左高,则一定是插入在右子树的左子树才会导致失衡
rd=rc->lchild;
switch(rd->bf)
{
case LH:
(*T)->bf=EH;
rc->bf=RH;
break;
case EH:
(*T)->bf=rc->bf=EH;
break;
case RH:
(*T)->bf=RH;
rc->bf=EH;
break;
}
rd->bf=EH;
R_Rotate(&(*T)->rchild);
L_Rotate(T);
}
}
int EQ(int a,int b)
{
return a==b;
}
int LT(int a,int b)
{
return a<b;
}