爲什麼需要平衡二叉樹?不平衡的二叉排序樹的查找效率是非常低的,不平衡的最壞情況就是斜樹,查找的時間複雜度是O(n),等同於順序查找。因此我們在構建時就讓這棵二叉排序樹是平衡二叉樹,此時的查找時間複雜度是O(logn),插入和刪除也爲O(logn),這顯然是一種比較理想的動態查找表算法。
平衡二叉樹:是一種二叉排序樹,其中每一個節點的左子樹和右子樹的高度差至多等於1。它是一種高度平衡的二叉樹。
平衡因子:將二叉樹上結點的左子樹深度減去右子樹深度的值稱爲平衡因子BF(Balance Factor)。
最小不平衡子樹:距離插入結點最近,且平衡因子的絕對值大於1的結點爲根的子樹,我們稱爲最小不平衡子樹。
平衡二叉樹構建的基本思想就是在構建二叉排序樹的過程中,每當插入一個結點時,先檢查是否因插入而破壞了樹的平衡性,若是,則找出最小不平衡子樹。在保持二叉排序樹特性的前提下,調整最小不平衡子樹中各結點之間的鏈接關係,進行相應的旋轉,使之成爲新的平衡子樹。
1、當最小不平衡子樹根結點的平衡因子BF是大於1時,就右旋;小於-1時就左旋。
2、插入結點後,最小不平衡子樹的BF與它的子樹的BF符合相反時,就需要對結點先進行一次旋轉使得符號相同後,再反向旋轉一次才能夠完成平衡操作。
#define EH 0
#define LH +1
#define RH -1
typedef struct BiTNode
{
int data;
int bf;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
void R_Rotate(BiTree *P)
{
BiTree L;
L = (*P)->lchild;
(*P)->lchild = L->rchild;
L->rchild = (*P);
*P = L;
}
void L_Rotate(BiTree *P)
{
BiTree R;
R = (*P)->rchild;
(*P)->rchild = R->lchild;
R->lchild = (*P);
*P = R;
}
void LeftBalance(BiTree *T)
{
BiTree L, Lr;
L = (*T)->lchild;
switch (L->bf)
{
case LH:
R_Rotate(T);
(*T)->bf = L->bf = EH;
break;
case RH:
Lr = L->rchild;
switch (Lr->bf)
{
case LH:
(*T)->bf = RH;
L->bf = EH;
break;
case EH:
L->bf = (*T)->bf = EH;
break;
case RH:
L->bf = LH;
(*T)->bf = EH;
break;
}
Lr->bf = EH;
L_Rotate(&(*T)->lchild);
R_Rotate(T);
}
}
void RightBalance(BiTree *T)
{
BiTree R, Rl;
R = (*T)->rchild;
switch(R->bf)
{
case RH:
(*T)->bf = R->bf = EH;
L_Rotate(T);
break;
case LH:
Rl = R->lchild;
switch(Rl->bf)
{
case LH:
(*T)->bf = EH;
R->bf = RH;
break;
case EH:
(*T)->bf = R->bf = EH;
break;
case RH:
(*T)->bf = LH;
R->bf = EH;
break;
}
Rl->bf = EH;
R_Rotate((*T)->rchild);
L_Rotate(T)
}
}
Status InsertAVL(BiTree *T, int e, Status *taller)
{
if (!*T)
{
*T = (BiTree)malloc(sizeof(BiTNode));
(*T)->data = e;
(*T)->lchild = (*T)->rchild = NULL;
(*T)->bf = EH;
*taller = TRUE;
}
else
{
if ((*T)->data == e)
{
taller = FALSE;
return FALSE;
}
if ((*T)->data > e)
{
if (!InsertAVL(&(*T)->lchild, e, taller))
return FALSE;
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 ((*T)->data < e)
{
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 RH:
RightBalance(T);
taller = FALSE;
break;
}
}
}
}
return TRUE;
}
void main()
{
int i;
int a[10] = {3, 2, 1, 4, 5, 6, 7, 10, 9, 8};
Status taller;
BiTree T = NULL;
for (i = 0; i < a.10; a++)
{
InsertAVL(&T, a[i], &taller);
}
}