至于什么是AVL树和AVL树的一些概念问题在这里就不多说了,下面是我写的代码,里面的注释非常详细地说明了实现的思想和方法。
因为在操作时真正需要的是子树高度的差,所以这里采用-1,0,1来表示左子树和右子树的高度差,而没有使用记录树的高度的方法。
代码如下:
#define FALSE 0
#define TRUE 1
#define LH 1
#define EH 0
#define RH -1
typedef struct AVLNode
{
DataType cData;
int nBf; //结点的平衡因子,-1表示右子树的深度比左子树高1
//0表示左子树与右子树深度相等
//1表示左子树的深度比右子树高1
struct AVLNode *LChild;
struct AVLNode *RChild;
}AVLNode,*AVLTree;
typedef int BOOL;
void R_Rotate(AVLTree *pAT)
{
//对以*pAT为根的二叉树作右旋转处理,处理之后pAT指向新的树根结点
//即旋转处理之前的左子树的根结点
AVLTree lc = (*pAT)->LChild;
(*pAT)->LChild = lc->RChild;
lc->RChild = *pAT;
*pAT = lc;
}
void L_Rotate(AVLTree *pAT)
{
//对以*pAT为根的二叉树作左旋转处理,处理之后pAT指向新的树根结点
//即旋转处理之前的右子树的根结点
AVLTree rc = (*pAT)->RChild;
(*pAT)->RChild = rc->LChild;
rc->LChild = *pAT;
*pAT = rc;
}
void LeftBalance(AVLTree *pAT)
{
//对以指针pAT所指结点为根的二叉树作左平衡旋转处理,
//本算法结束时指针pAT指向新的结点
AVLTree lc = (*pAT)->LChild; //lc指向*pAT的左子树根结点
AVLTree rd = NULL;
if(lc)
switch(lc->nBf) //检查*pAT的左子树的平衡度,并作相应平衡处理
{
case LH: //新结点插入在*pAT的左孩子的左子树上,要作单右旋转处理
(*pAT)->nBf = lc->nBf = EH;
R_Rotate(pAT);
break;
case RH: //新结点插入在*pAT的左孩子的右子树上,要作双旋转处理
rd = lc->RChild;
switch(rd->nBf) //修改*pAT及其左孩子的平衡因子
{
case LH:
(*pAT)->nBf = RH;
lc->nBf = EH;
break;
case EH:
(*pAT)->nBf = lc->nBf = EH;
brea