AVL树
本质是二叉查找树,但具以下特点:
- 一棵空树;
- 左右两个子树的高度差的绝对值不超过1,且左右两个子树都分别是平衡二叉树。
- 在AVL树中任何节点的两个子树的高度最大差别为一,又称平衡二叉树。
板子
节点插入+层序输出
#include<bits/stdc++.h>
using namespace std;
typedef struct node{
struct node *lchild;
struct node *rchild;
int val,height;
}*tree,node;
//求树的高度
int getHeight(tree &T)
{
if(T==NULL)return -1;
return T->height;
}
//单旋转右旋
void R(tree &T)
{
tree L=T->lchild;
T->lchild=L->rchild;
L->rchild=T;
T->height=max(getHeight(T->lchild),getHeight(T->rchild))+1;
L->height=max(getHeight(L->lchild),getHeight(L->rchild))+1;
T=L; //此时L成为根节点了(可参考AVL的插入的左左情况的右旋图)
}
//单旋转左旋
tree L(tree &T)
{
tree R=T->rchild;
T->rchild=R->lchild;
R->lchild=T;
T->height=max(getHeight(T->lchild),getHeight(T->rchild))+1;
R->height=max(getHeight(R->lchild),getHeight(R->rchild))+1;
T=R; //此时R成为根节点了(可参考AVL的插入的左左情况的左旋图)
}
//双旋转,先左后右
void LR(tree &T)
{
L(T->lchild);
R(T);
}
//双旋转,先右后左
tree RL(tree &T)
{
R(T->rchild);
L(T);
}
void insert(tree &T,int x)
{
if(T==NULL) //如果树为空
{
T=new node;
T->val=x;
T->lchild=T->rchild=NULL;
T->height=0;
}
else if(x<T->val) //插入到T结点的左子树上
{
insert(T->lchild,x);//先插入,后旋转
if(getHeight(T->lchild)-getHeight(T->rchild)==2) //只有可能是这个
{
if(x<T->lchild->val) //左左情况,只需要右旋转
R(T);
else //左右情况,双旋转,先左
LR(T);
}
}
else if(x>T->val)
{
insert(T->rchild,x);
if(getHeight(T->rchild)-getHeight(T->lchild)==2)
{
if(x>T->rchild->val) //右右情况,进行左旋
L(T);
else //左右情况,双旋转,先右
RL(T);
}
}
//如果这个数已经存在,那么不进行插入
T->height=max(getHeight(T->lchild),getHeight(T->rchild))+1;
}
//层序遍历输出
void getLevel(tree &T)
{
if(T==NULL)return;
queue<tree>q;
q.push(T);
while(!q.empty())
{
tree t=q.front();
q.pop();
cout<<t->val<<" ";
if(t->lchild!=NULL)q.push(t->lchild);
if(t->rchild!=NULL)q.push(t->rchild);
}
}
int main()
{
tree T=NULL;
int n;scanf("%d",&n);
for(int i=0;i<n;++i)
{
int x;scanf("%d",&x);
insert(T,x);
}
getLevel(T);
return 0;
}