【知识点】平衡二叉树(AVL树)
平衡二叉树的概念
根结点左子树高度-右子树高度为平衡因子(BF)。
所有子树平衡因子绝对值小于等于1的的查找二叉树称为平衡二叉树。
插入后需要使用旋转进行纠正。
距离插入节点最近的,并且平衡因子的绝对值大于1的节点为根节点的子树称为最小不平衡子树。
只需要对最小不平衡子树进行旋转纠正即可。
旋转纠正
两种旋转方式
- 左旋
- 旧根结点作为新根节点的左子树
- 新根节点的原左子树作为旧根结点的右子树
- 右旋
- 旧根结点作为新根节点的右子树
- 新根节点的原右子树作为旧根结点的左子树
四种纠正类型
- LL型:右旋
- RR型:左旋
- LR型:先左旋后右旋
- RL型:先右旋后左旋
完整代码
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct TreeNode{
//数据域
int data;
//指针域
TreeNode *LChild,*RChild;
//属性
int height;
//构造器
TreeNode(int a){
LChild = RChild = NULL;
height = 0;
this->data = a;
}
}*Node;
//返回新根结点的四种纠正
Node LLRotate(Node root){
Node temp = root->LChild;
root->LChild = temp->RChild;
temp->RChild = root;
return temp;
}
Node RRRotate(Node root){
Node temp = root->RChild;
root->RChild = temp->LChild;
temp->LChild = root;
return temp;
}
Node LRRotate(Node root){
root->LChild = RRRotate(root->LChild);
return LLRotate(root);
}
Node RLRotate(Node root){
root->RChild = LLRotate(root->RChild);
return RRRotate(root);
}
//递归求树高
int heit(Node root){
if(root == NULL)
return 0;
return max(heit(root->LChild)+1, heit(root->RChild)+1);
}
//求该节点平衡因子
int BF(Node now){
return heit(now->LChild) - heit(now->RChild);
}
//平衡函数
Node Balance(Node root){
int fact = BF(root);
if(fact > 1){
if(BF(root->LChild) > 0) //LL的情况
root = LLRotate(root);
else //LR的情况
root = LRRotate(root);
}
else if(fact < -1){
if(BF(root->RChild) < 0) //RR的情况
root = RRRotate(root);
else //RL的情况
root = RLRotate(root);
}
return root;
}
//插入节点
Node Insert(Node now,int a){
if(now == NULL){
now = new TreeNode(a);
return now;
}
if(a == now->data)
return now;
//递归
if(a < now->data)
now->LChild = Insert(now->LChild,a);
else
now->RChild = Insert(now->RChild,a);
now = Balance(now); //平衡路径上的每个节点
return now;
}
//中序遍历打印二叉树
void print(Node now){
if(now == NULL)
return;
print(now->LChild);
printf("%d ",now->data);
print(now->RChild);
return;
}
//直观简单打印二叉树
void printTree(Node n)
{
static int level = -1; //记录是第几层次
int i;
if (NULL == n)
return;
level++;
printTree(n->RChild);
for (i = 0; i < level; i++)
printf("\t");
printf("%2d\n", n->data);
printTree(n->LChild);
level--;
}
int main(){
//在主函数中测试
int array[10] = {4,5,6,3,2,8,7,9,0,1};
//构造平衡二叉树
Node root = NULL;
for(int i = 0;i<10;i++)
{
root = Insert(root,array[i]);
printf("\n\n\n");
printTree(root);
}
print(root);
return 0;
}
测试输出结果为
4
5
4
6
5
4
6
5
4
3
6
5
4
3
2
8
6
5
4
3
2
8
7
6
5
4
3
2
9
8
7
6
5
4
3
2
9
8
7
6
5
4
3
2
0
9
8
7
6
5
4
3
2
1
0
0 1 2 3 4 5 6 7 8 9
其中,添加6时RR调整,添加2时LL调整,添加7时RL调整,添加1时LR调整,可以自行感受。

浙公网安备 33010602011771号