1. 程式人生 > >AVL樹的實現(程式碼實現)

AVL樹的實現(程式碼實現)

AVL又叫平衡二叉樹,它是二叉搜尋樹的升級版,為什麼有 平衡二叉樹呢?是因為有些二叉搜尋樹要兼顧查詢和插入的功能,那麼很有可能在插入的情況下,有一種極端情況就是插入的值老是小於根節點,這樣子的話,資料都被插入在了二叉搜尋樹的左側,出現左側一溜下去的情況,這樣的二叉搜尋樹跟個連結串列差不多,查詢效率是很低的,為了在插入的同時調整書高,引入了AVL樹。
在AVL樹中 最難的應該就是通過樹的旋轉來調整平衡的問題 它分為四種 下面是他們的程式碼實現:
(1):LL旋轉:

Tnode* LLInsert(Tnode * A){
	Tnode * B = A -> left;
	A -> left = B -> right;
	B -> right = A;
	A ->Height =max(GetHeight(A->left),GetHeight(A->right)) +1;
	B ->Height =max(GetHeight(B->left),A->Height) +1;
	return B ;

(2):RR旋轉

Tnode* RRInsert(Tnode *A){
    Tnode *B = A -> right;
    A -> right = B -> left;
    B -> left = A ;
    A ->Height = max(GetHeight(A->left),GetHeight(A->right))+1;
    B ->Height = max(GetHeight(B->left),GetHeight(B->right))+1;
    return B;
}

(3):LR旋轉:

Tnode* LRInsert(Tnode *A){
    A->left = RRInsert(A->left);
    return LLInsert(A);
}

(4);RL旋轉:

Tnode* RLInsert(Tnode *A){
    A -> right = LLInsert(A->right);
    return RRInsert(A);
}

其中LL旋轉和RR旋轉是最基礎的兩種旋轉,而另外RL和RL旋轉都是基於這兩種旋轉的。
下邊是AVL樹的插入(重點),其實也不是很難,就是在二叉搜尋樹的基礎上增加了兩個操作,插入完成後的旋轉調整 和樹高調整

Tnode * Insert(Tnode *T,int x){
	if(!T){
		T = (Tnode *)malloc(sizeof(Tnode));
		T -> data = x;
		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 = LLInsert(T);
			else T = LRInsert(T);

		}
	}
	else if(x > T->data){
		T -> right = Insert(T -> right, x);
		if(GetHeight(T -> right) - GetHeight(T -> left) == 2)
			if(x > T -> right -> data) T = RRInsert(T);
			else T = RLInsert(T);
	}
	T -> Height = max(GetHeight(T -> left),GetHeight(T -> right)) + 1;

	return T;
}

總結:AVL樹是一種升級版的搜尋樹,如果我們判斷出某些實際情況需要用到樹的時候 並且對樹的操作有插入和查詢的時候,我們就要考慮使用AVL樹了,如果僅僅是查詢的話二叉搜尋樹足矣