哇,真的一直不会平衡二叉树的旋转。今天晚上看了好久,也感觉有点似懂非懂。不过推荐大家几个网站,一个是中国大学mooc上面浙江大学陈姥姥讲的数据结构,还有就是这个可视化网站VisuAlgo,看看老师讲的,自己动手多画一画,我觉得慢慢就理解了,记住了。
- 题目
04-树5 Root of AVL Tree (25分)
- 分析
本题是2013年浙江大学计算机学院免试研究生上机考试真题,是关于AVL树的基本训练。难点就在于AVL树的旋转操作。要在理解的基础上很快能写出来。
- 我的代码
#include<stdio.h>
#include<stdlib.h>
typedef struct AVLNode* AVLTree;
struct AVLNode{
int data;
int height;
struct AVLNode* left;
struct AVLNode* right;
};
int max(int a,int b);
int getHeight(AVLTree T);
AVLTree SingleLeftRotation(AVLTree A); //左单旋
AVLTree SingleRightRotation(AVLTree A); //右单旋
AVLTree LeftRightRotation (AVLTree A); //左右双旋
AVLTree RightLeftRotation (AVLTree A); //右左双旋
AVLTree Insert(int X,AVLTree T);
int main()
{
int N,i,x;
scanf("%d",&N);
AVLTree T = NULL;
for(i=0; i<N; i++){
scanf("%d",&x);
T = Insert(x,T);
}
printf("%d\n",T->data);
return 0;
}
int max(int a,int b){
return a>b?a:b;
}
int getHeight(AVLTree T){
if(T == NULL){
return -1; //-1表示不存在
}
return T->height;
}
AVLTree SingleLeftRotation(AVLTree A){
/* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */
AVLTree 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), getHeight(B->right)) + 1;
return B;
}
AVLTree SingleRightRotation(AVLTree A){
AVLTree 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;
}
AVLTree LeftRightRotation (AVLTree A){
/* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */
/* 将A、B与C做两次单旋,返回新的根结点C */
/* 将B与C做右单旋,C被返回 */
A->left = SingleRightRotation(A->left);
/* 将A与C做左单旋,C被返回 */
return SingleLeftRotation(A);
}
AVLTree RightLeftRotation (AVLTree A){
/*注意:A必须有一个右子结点B,且B有一个左子结点C*/
/* 将A、B与C做两次单旋,返回新的根结点C */
//B、C先左单旋,C被返回
A->right = SingleLeftRotation(A->right);
//A、C右单旋,C被返回
return SingleRightRotation(A);
}
AVLTree Insert(int X,AVLTree T){
if(T == NULL){
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(X,T->left);
if(getHeight(T->left)-getHeight(T->right) == 2){
if(X < T->left->data)
T = SingleLeftRotation(T); //左单旋
else
T = LeftRightRotation(T); //左右双旋
}
}else if(X > T->data){
T->right = Insert(X, T->right);
if(getHeight(T->right)-getHeight(T->left) == 2 ){
if( X > T->right->data )
T = SingleRightRotation(T); //右单旋
else
T = RightLeftRotation(T); //右左双旋
}
}
// 别忘了更新树高,就算没有旋转,高度值也可能改变
T->height = max( getHeight(T->left), getHeight(T->right) ) + 1;
return T;
}