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树了,如果仅仅是查找的话二叉搜索树足矣