#include<stdio.h>
#include<stdlib.h>
//平衡树的实现
typedef struct AvlNode{
int element;
struct AvlNode *left;
struct AvlNode *right;
int height;
}*AvlTree;
int Height(AvlTree T){
if(T==NULL){
return -1;
}else{
return T->height;
}
}
AvlTree SingleTotateWithLeft(AvlTree T);
AvlTree SingleTotateWithRight(AvlTree T);
AvlTree DoubleTotateWithLeft(AvlTree T);
AvlTree DoubleTotateWithRight(AvlTree T);
void print(AvlTree T){
//先序遍历 根左右
if(T){
printf("%d ",T->element);
print(T->left);
print(T->right);
}
}
int Max(int k1,int k2){
if(k1>k2){
return k2;
}else{
return k1;
}
}
//插入
AvlTree Insert(int X,AvlTree T){
//分情况计论
//树为空
if(T==NULL){
//生成一个新树
T=(AvlTree)malloc(sizeof(struct AvlNode));
T->element=X;
T->left=NULL;
T->right=NULL;
T->height=0;
}
//不空
else if(X>T->element){
//比树根元素大,到右子树
//将右边的子树当成一个新的树
T->right=Insert(X,T->right);
if(Height(T->left)-Height(T->right)==-2){
//需要重新平衡 判断是右右还是右左
if(X>T->right->element){
//右右 单旋
T=SingleTotateWithRight(T);
} else{
//右左 双旋
T=DoubleTotateWithRight(T);
}
}
}else if(X<T->element){
//比根元素小,到左子树
T->left=Insert(X,T->left);
if(Height(T->left)-Height(T->right)==2){
//需要重新平衡,判断是左左还是左右
if(X>T->left->element){
//左右 双旋
T=DoubleTotateWithLeft(T);
}else{
//左左 单旋
T=SingleTotateWithRight(T);
}
}
}
T->height=Max(Height(T->left),Height(T->right))+1;
return T;
}
//左单旋
AvlTree SingleTotateWithLeft(AvlTree T){
//获取到T的左孩子
AvlTree P=T->left;
//p将成为新的结点,将其右孩子转为T的左孩子
T->left=P->right;
P->right=T;
//旋转后高度重新处理
T->height=Max(Height(T->left),Height(T->right))+1;
P->height=Max(Height(T),Height(P->left))+1;
//返回P替代T
return P;
}
//右单旋
AvlTree SingleTotateWithRight(AvlTree T){
//获取T右孩子
AvlTree P=T->right;
//p将成为新的结点,将其左孩子转为T的右孩子
T->right=P->left;
P->left=T;
//旋转后重新处理高度
T->height=Max(Height(T->left),Height(T->right))+1;
P->height=Max(Height(T),Height(P->right))+1 ;
//返回p代替T
return P;
}
//左双旋
AvlTree DoubleTotateWithLeft(AvlTree T){
//获取的节点为高两层的节点
//先进行左单旋
T->left=SingleTotateWithLeft(T->left);
//再进行右单旋
return SingleTotateWithRight(T);
}
//右双旋
AvlTree DoubleTotateWithRight(AvlTree T){
//获取的节点为高两层的节点
//先进行右单旋
T->right=SingleTotateWithRight(T->right);
//再返回左单旋的结果
return SingleTotateWithLeft(T);
}
//测试
int main(){
AvlTree T=NULL;
T=Insert(4,T);
T=Insert(2,T);
T=Insert(6,T);
T=Insert(1,T);
T=Insert(3,T);
T=Insert(5,T);
T=Insert(15,T);
T=Insert(7,T);
T=Insert(16,T);
T=Insert(14,T);
//打印出树的结果
print(T);
}
avl树实现
最新推荐文章于 2022-10-08 10:25:25 发布