平衡二叉树定义:任一节点的左右子树高度差的绝对值不超过1。
定义BF为平衡因子,HL和HR分别为T的左右子树的高度,满足|BF|<=1。
节点数为n的平衡二叉树的最大高度为O(lgn)。
查找、插入和删除在平均和最坏情况下的时间复杂度都是
O(logn),增加和删除可能需要通过一次或多次树旋转来重新平衡这棵树。
在AVL树中插入一个节点的算法:
(1)若树为空,插入元素作为AVL树的根节点,树的深度增1
(2)若插入元素和根节点值相等,则不进行处理
(3)若插入元素的值小于根节点值,而且在左子树中不存在和插入元素相同的节点,则将元素插入该树的左子树,插入之后左子树的深度增加1,分别就下列不同情况处理:
a,根节点的平衡因子为-2(右子树的深度大于左子树深度,则将平衡因子调整为-1)
b,根节点的平衡因子为2(右子树的深度小于左子树深度,则将平衡因子调整为1)
(4)若插入元素的值大于根节点值,而且在右子树中不存在和插入元素相同的节点,则将元素插入该树的右子树,插入之后右子树的深度增加1,分别就不同情况进行处理。
AVL树的调整策略:
T1, T2, T3 , T4 子树
(1)插入点位于左子树的左子树
(2)插入点位于左子树的右子树
(3)插入点位于右子树的右子树
(4)插入点位于右子树的左子树
typedef struct ACLNode *Position;
typedef Position AVLTree;
struct AVLNode{
ElementType Data;//节点数据
AVLTree Left;//指向左子树
AVLTree Right;//指向右子树
int Height;//树高
};
int Max(int a, int b){
return a>b ? a : b;
}
AVLTree SingleLeftRotation(AVLTree A){
//A必须有一个右子结点B
AVLTree B = A->Right;
AVLTree C = B->Left;
B->Right = A;
A->Left = C;
A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
B->Height = Max(GetHeight(B->Left), GetHeight(B->Right)) + 1;
return B;
}
AVLTree SingleRightRotation(AVLTree A){
//A必须有一个左子结点B
AVLTree B = A->Left;
AVLTree C = B->Right;
B->Right = A;
A->Left = C;
A->Height = Max(GetHeight(A->Left), GetHeight(A->Right))+1;
B->Height = Max(GetHeight(B->Left), GetHeight(B->Right)) + 1;
return B;
}
AVLTree DoubleLeftRightRotation(AVLTree A){
//A必须有一个左子结点B,且B必须有一个右子结点C,先左移,再右移
A->Left = SingleLeftRotation(A->Left);
return SingleRightRotation(A);
}
AVLTree DoubleRightLeftRotation(AVLTree A){
//A必须有一个右子结点B,且B必须有一个左子结点C,先右移,再左移
A->Right = SingleRightRotation(A->Left);
return SingleLeftRotation(A);
}
AVLTree Insert(AVLTree T, ElementType X) {
if(!T) {
T = (AVLTree)malloc(sizeof(struct AVLNode));
T->Data = X;
T->Height = 0;
T->Left = T->Right = NULL;
} else if(X < T->Data) {
//插入左子树
T->Left = Insert(T->Left, X);
if (GetHeight(T->Left) - GetHeight(T->Right) == 2) {
if (X < T->Left->Data){//右单旋
T= SingleRightRotation(T);
} else {
T = DoubleLeftRightRotation(T);//左右旋转
}
}
} else if(X > T->Data) {
//插入右子树
T->Right = Insert(T->Right, X);
if(GetHeight(T->Left) - GetHeight(T->Right) == -2) {
if(X > T->Right->Data){
T = SingleLeftRotation()T;//左单旋
} else {
T = SingleRightLeftRotation(T);//右左单旋
}
}
}
T->Height = Max(GetHeight(T->Left), GetHeight(T->Right));
return T;
}
AVL树的删除元素同二叉查找树相同,需要删除后调整树的平衡因子,调整过程同插入元素后的调整方式相同。