定义: 为避免树的高度增长过快,降低二叉排序树的性能,规定在插入和删除二叉树结点时,要保证任意结点的左右子树的高度差的绝对值不超过1.将这样的二叉树称为平衡二叉树,简称平衡树。
平衡因子: 结点左子树和右子树的高度差,平衡树平衡因子取值只可能是-1、0、1。
1、LL平衡旋转(右单旋转)
在结点A的左孩子(L)的左子树(L)上插入新节点。
/* LL单旋 */
static Position SingleRotateWithRight(Position A)
{
Position B;
B = A->Left;
A->Left= B->Right;
B->Left = A;
A->Height = Max(Height(A->Left), Height(A->Right)) + 1;
B->Height = Max(Height(B->Left),A->Height) + 1;
return B; /*New root */
}
2、RR平衡旋转(左单旋转)
在结点A的右孩子(R)的右子树(R)上插入新节点。
/* 向左单旋 */
static Position SingleRotateWithLeft(Position A)
{
Position B;
B= A->Right;
A->Right= B->Left;
B->Left= A;
A->Height = Max(Height(A->Left), Height(A->Right)) + 1;
B->Height = Max(A->Height,Height(B->Right)) + 1;
return B; /* New Root */
}
3、LR平衡旋转(先左后右双旋转)
在结点A的左孩子(L)的右子树(R)上插入新节点。
/* 先左后右双旋 */
static Position DoubleRotateWithLeft(Position A)
{
/* Rotate between K1 and K2 */
A->Left = SingleRotateWithRight(A->Left);
/* Rotate between K3 and K2 */
return SingleRotateWithLeft(A);
}
2、RL平衡旋转(先右后左双旋转)
在结点A的右孩子(R)的左子树(L)上插入新节点。
/* 先右后左双旋 */
static Position DoubleRotateWithRight(Position A)
{
A->Right = SingleRotateWithLeft(A->Right);
return SingleRotateWithRight(A);
}
例子:
插入 15、3、7、10、9、8,生成平衡树。
代码实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct AvlNode *Position;
typedef struct AvlNode *AvlTree;
typedef int ElementType;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
struct AvlNode
{
ElementType Element;
AvlTree Left;
AvlTree Right;
int Height;
};
AvlTree MakeEmpty(AvlTree T)
{
if (T != NULL)
{
MakeEmpty(T->Left);
MakeEmpty(T->Right);
free(T);
}
return NULL;
}
/**
* 计算Avl节点高度
* @param P 节点P
* @return 树高
*/
static int Height(Position P)
{
if (P == NULL