• 平衡二叉树,是一种二叉排序树,其中每一个节点的左子树和和右子树的高度差至多等于1。
  • 平衡因子,将二叉树的左子树深度减去右子树深度的值称为平衡因子BF(Balance Factor)。
  • 最小不平衡子树,距离插入结点最近的,且平衡因子的绝对值大于1的结点为根的子树。
undefined

平衡二叉树 构建

​平衡二叉树构建的基本思想就是在构建二叉排序树的过程中,每当插人一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点间的链接关系,进行相应的旋转,使之成为新的平衡子树。

a[10]={3,2,1,4,5,6,7,10,9,8} 的构建过程
图解:

undefined
undefined
undefined
undefined

图11不能简单的旋转,仔细观察图就会发现,根本原因在于结点7的BF是-2,而结点10的BF是1,符号不同意。前面的几次旋转,无论左还是右旋,最小不平衡树的根节点与它的子节点的BF符号是相同的。 这就是不能直接旋转的关键。
所以需要先把它们转到符号统一:对结点9和结点10进行右旋,再以结点7位最小不平衡子树进行左旋。

undefined

主要算法:

/*二叉树的二叉链表结点结构定义*/
typedef struct BitNode				   /*结点结构*/
{
	int data;                          /*结点数据*/
	int bf;                            /*结点的平衡因子*/
	struct BitNode *lchild,*rchild;    /*左右孩子指针*/
}BitNode,*BiTree;
/*对以P为根的二叉树作右旋处理*/
/*处理之后P指向新的树根结点,即旋转处理之前的左子树的根节点*/
void R_Rotate(BiTree *P)
{
	BiTree L;
	L=(*P)->lchild;
	(*P)->lchild = L->rchild;
	L->rchild=(*P);
	*P =L;
}

右旋图解:
undefined

#define LH 1
#define EH 0
#define RH -1
/*对以指针T所指根节点为根的二叉树作左平衡旋转处理*/
/*本算法结束时,指针T指向新的根节点*/
void LeftBalance(BiTree *T)
{
	BiTree L,Lr;
	L=(*T)->lchild;    /*L指向T的左子树根节点*/
	switch(L->bf)
	{    /*检查T的左子树的平衡度,并作相应平衡处理*/
		case LH:   /*新结点插入在T的左孩子的左子树上,作右旋处理*/
			(*T)->bf=L->bf=EH;
			R_Rotate(T);
			break;
		case RH:   /*新结点插入在T的左孩子的右子树上,作双旋处理*/
			Lr = L->rchild;   /*Lr指向T的左孩子的右子树根*/
			switch(Lr->bf)    /*修改T及其左孩子的平衡因子*/
			{
				case LH:
					(*T)->bf = RH;
					L->bf = EH;
					break;
				case EH:
					(*T)->bf = L->bf = EH;
					break;
				case RH:
					(*T)->bf = EH;
					L->bf = LH;
					break;
			}
			Lr->bf = EH;
			L_Rotate(&(*T)->lchild);   /*对T的左子树作左旋平衡处理*/
			R_Rotate(T);               /*对T作右旋平衡处理*/
			break;
	}
}

左平衡旋转图解:

undefined

主函数:

//若在平衡的二叉排序树T中不存在和e有相同关键字的结点,
//则插入一个数据元素为e的新结点并返回1,否则返回0。若因插入而使二叉排序树失去平衡,
//则作平衡旋转处理,布尔变量taller反映T长高与否
Status InsertAVL(BiTree *T,int e,Status *taller)
{
	if(!*T)
	{   /*插入新结点,树“长高”,置taller为TRUE */
		*T=(BiTree)malloc(sizeof(BiTNode));
		(*T)->data = e;
		(*T)->lchild=(*T)->rchild = NULL;
		(*T)->bf=EH;
		*taller = TRUE;
	}
	else
	{
		if(e==(*T)->data)
		{   /*树中已存在和e相同关键字的结点则不再插入*/
			*taller=FALSE;
			return FALSE;
		}
		if(e<(*T)->data)
		{   /*继续在T的左子树中进行搜索*/
			if(!InsertAVL(&(*T)->lchild,e,taller))
				return FALSE;
			if(*taller) /*已插入到T的左子树中且左子树高度增加*/
			{
				switch((*T)->bf)   /*检查T的平衡度*/
				{
				case LH:  /*原本左子树比右子树高,需要作平衡处理*/
					LeftBalance(T);
					*taller=FALSE;
					break;
				case EH:  /*原本左右子树等高,现因左子树增高而树增高*/
					(*T)->bf=LH;
					*taller = TRUE;
					break;
				case RH:  /*原本右子树高,现左右子树等高*/
					(*T)->bf = EH;
					*taller = FALSE;
					break;
				}
			}
		}
		else
		{   /*继续在T的左子树中进行搜索*/
			if(!InsertAVL(&(*T)->rchild,e,taller))
				return FALSE;
			if(*taller)
				switch((*T)->bf)
				{
					case LH:
						(*T)->bf=EH;
						*taller = FALSE;
						break;
					case EH:
						(*T)->bf=RH;
						*taller = TRUE;
						break;
					case LH:
						RightBalance(T);
						*taller = FALSE;
						break;
				}
			}
		}
	}
	return TRUE;
}