#include<stdio.h>
#include<stdlib.h>
#define LH 1 //左边高
#define EH 0 //等高
#define RH -1 //右边高
//右单旋转
/*
p
/ \
L Pr
/ \
Ll Lr
|
N
*/
void R_Rotate(BiTree *p)
{
BiTree L;
//将根的左子树赋给L
L = (*p)->lchild;
//根的左子树要变成L的右子树
(*p)->lchild = L->rchild;
//L的右子树挂接P的左子树
L->rchild = (*p);
//p指向新的根节点
*p = L;
}
/*
p
/ \
Pr R
/ \
Ll Lr
|
N
*/
//向左旋转
void L_Rotate(BiTree *p)
{
BiTree R;
//R指向p的右子树
R = (*p)->rchild;
(*p)->rchild = R->lchild;
R->lchild = (*p);
(*p) = R;
}
void LeftBalance(BiTree *T)
{
BiTree L, Lr;
L = (*T)->lchild;
switch (L->bf)
{
//左边高
case LH:
(*T)->bf = L->bf = EH;
//新节点插入在T的左孩子的左子树上,要做单右旋处理
R_Rotate(T);
break;
case RH://新节点插入在T的左孩子的右子树上,要做双旋处理
/*
插入后的左子树的bf跟根的bf不同,左子树为负,根为正,要进行双旋,先左旋,后右旋
P
/ \
L Pr
/ \ \
Ll Lr ...
/ \
Lr1 Lrr
|
N
Lr
/ \
L p
/ \ / \
Ll Lr1 Lrr Pr
| \
N ...
*/
//Lr指向T的左孩子的右子树根
Lr = L->rchild;
switch (Lr->bf)
{
//这里对应了三种情况,具体要画出最后的图
case LH:
(*T)->bf = RH;
L->bf = EH;
break;
case EH:
(*T)->bf = L->bf = EH;
break;
case RH:
(*T)->bf = EH;
L->bf = LH;
break;
}
Lr->bf = EH;
L_Rotate(&(*T)->lchild);//对T的左子树作左旋平衡处理
R_Rotate(T);//对T作右旋平衡处理
}
}
void RightBalance(BiTree *T)
{
BiTree L, Lr;
L = (*T)->rchild;
switch (L->bf)
{
case RH:
L->bf = (*T)->bf = EH;
//传二级指针的地址
L_Rotate(T);
break;
case LH:
Lr = L->lchild;
switch (Lr->bf)
{
case LH:
(*T)->bf = RH;
L->bf = EH;
break;
case EH:
(*T)->bf = L->bf = EH;
break;
case RH:
(*T)->bf = LH;
L->bf = EH;
break;
}
Lr->bf = EH;
R_Rotate(&(*T)->rchild);
L_Rotate(T);
}
}
//插入avl树中
Status InsertAVL(BiTree *T, int e, Status *taller)
{
if (!*T)
{
*T = (BiTree)malloc(sizeof(BiTNode));
(*T)->data = e;
(*T)->lchild = (*T)->rchild = NULL;
(*T)->bf = EH;
//插入成功后赋值为TRUE
*taller = TRUE;
}
else
{
if (e == (*T)->data)
{
*taller = FALSE;
return FALSE;
}
//数据比根节点的值小,要插到左子树上
if (e < (*T)->data)
{
if (!InsertAVL(&(*T)->lchild, e, taller))//没有插入
return FALSE;
//已经插入
if (*taller)
{
//检查T的平衡度
switch ((*T)->bf)
{
case LH://原本左子树比右子树高,需要作左平衡处理
LeftBalance(T);
*taller = FALSE;
break;
case EH://原本左右子树等高,现在因为左子树增高而树增高
(*T)->bf = LH;
*taller = TRUE;
break;
case RH:
//原本右子树比左子树高,现在右子树跟左子树等高
(*T)->bf = EH;
*taller = FALSE;
break;
}
}
}
else
{
//插入失败
if (!InsertAVL(&(*T)->rchild, e, taller))
{
return FALSE;
}
//已经插入
if (*taller)
{
switch ((*T)->bf)
{
case LH://原本左子树比右子树高,现在左右子树等高
(*T)->bf = EH;
*taller = FALSE;
break;
case EH: //原本左右等高,现在右高
(*T)->bf = RH;
*taller = TRUE;
break;
//原本右高,插入后右更高,要进行右平衡
case RH:
RightBalance(T);
*taller = FALSE;
break;
}
}
}
}
return TRUE;
}
//这里使用的是前序遍历
void TravelTree(BiTree *p)
{
BiTree T = *p;
if (T)
{
printf("%d",T->data);
TravelTree(T->lchild);
TravelTree(T->rchild);
}
}
大话数据结构AVL树理解
最新推荐文章于 2024-09-17 16:10:17 发布
1479

被折叠的 条评论
为什么被折叠?



