AVL樹的實現(程式碼實現)
阿新 • • 發佈:2018-11-22
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樹了,如果僅僅是查詢的話二叉搜尋樹足矣