平衡二叉樹

爲什麼需要平衡二叉樹?不平衡的二叉排序樹的查找效率是非常低的,不平衡的最壞情況就是斜樹,查找的時間複雜度是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);
 	}
 }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章