#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define LH 1 //left high
#define EH 0 //equal high
#define RH -1 //right high
#define TRUE 1
#define FALSE 0
typedef struct BiTNode
{
int data;
int bf;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void R_Rotate(BiTree *p)//右旋函数
{
BiTree L;//定义一个结点
L = (*p)->lchild;
(*p)->lchild = L->rchild;
L->rchild = (*p);
*p = L;
}
void L_Rotate(BiTree *p)//左旋函数
{
BiTree R;
R = (*p)->rchild;
(*p)->rchild = R->lchild;
R->lchild = (*p);
*p = R;
}
void LeftBalance(BiTree *T)//左平衡处理函数
{
BiTree L,Lr;
L = (*T)->lchild;//L指向左孩子
switch(L->bf)
{
case LH://如果
(*T)->bf = L->bf = EH;
printf("bal lh\n");
R_Rotate(T);
break;
case RH:
printf("bal rh\n");
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);
R_Rotate(T);
}
}
void RightBalance(BiTree *T)
{
BiTree R,Rl;
R = (*T)->rchild;
switch(R->bf)
{
case RH:
(*T)->bf = R->bf = EH;
L_Rotate(T);
break;
case LH:
Rl = R->lchild;
switch(Rl->bf)
{
case LH:
(*T)->bf = EH;
R->bf = RH;
break;
case RH:
(*T)->bf = LH;
R->bf = EH;
break;
case EH:
(*T)->bf = R->bf = EH;
break;
}
Rl->bf = EH;
R_Rotate(&(*T)->rchild);
L_Rotate(T);
}
}
int InsertAVL(BiTree *T,int e,bool taller)
{
if(! *T)//如果该树为空树,那么将数据赋值给根节点
{
*T = (BiTree)malloc(sizeof(BiTNode));
(*T)->data = e;
(*T)->lchild = (*T)->rchild = NULL;//左右孩子为空
(*T)->bf = EH;//左右等高
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)//插入成功,判断树长高了,查看是左子树长高还是右子树长高还是平衡
{
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;
}
}
}
}
}
int SearchAVL(BiTree T,int key,BiTree f,BiTree *p)
{
if(!T)
{
*p = f;
return TRUE;
}
else if(key == T->data)
{
*p = T;
return TRUE;
}
else if(key < T->data)
{
return SearchAVL(T->lchild,key,T,p);
}
else
{
return SearchAVL(T->rchild,key,T,p);
}
}
void CreateAVL(BiTree *T,int *key,int n)
{
int i;
*T = NULL;
bool taller = true;
for(i = 0; i < n; ++i)
{
InsertAVL(T,key[i],taller);
}
}
void inorder(BiTree p)
{
if(p!= NULL)
{
inorder(p->lchild);
printf("%d ",p->data);
inorder(p->rchild);
}
}
int DeleteAVL(BiTree *T,int e,bool shorter)
{
if(! *T)
{
return FALSE;
}
else if(e == (*T)->data)
{
BiTNode* q = NULL;
if((*T)->lchild == NULL)
{
q = *T;
(*T) = (*T)->rchild;
free(q);
shorter = true;
}
else if((*T)->rchild == NULL)
{
q = *T;
*T = (*T)->lchild;
free(q);
shorter = true;
}
else
{
q = (*T)->lchild;
while(q->rchild)
{
q = q->rchild;
}
(*T)->data = q->data;
DeleteAVL(&(*T)->lchild,q->data,shorter);
}
}
else if(e < (*T)->data)
{
if(!(DeleteAVL(&(*T)->lchild,e,shorter)))
{
return FALSE;
}
if(shorter)
{
switch((*T)->bf)
{
case LH:
(*T)->bf = EH;
shorter = true;
break;
case EH:
(*T)->bf = RH;
shorter = false;
break;
case RH:
RightBalance(T);
if((*T)->rchild->bf == EH)
{
shorter = false;
}
else
{
shorter = true;
}
break;
}
}
}
else
{
if(!(DeleteAVL(&(*T)->rchild,e,shorter)))
{
return FALSE;
}
if(shorter)
{
switch((*T)->bf)
{
case LH:
LeftBalance(T);
if((*T)->lchild->bf == EH)
{
shorter = false;
}
else
{
shorter = true;
}
break;
case EH:
(*T)->bf = LH;
shorter = false;
break;
case RH:
(*T)->bf = EH;
shorter = true;
break;
}
}
}
return true;
}
int main()
{
int i;
int n;
int num = 3;
int key[num];
bool shorter;
BiTree T = NULL;
shorter = false;
printf("please input the num\n");
for(i = 0; i < num; ++i)
{
scanf("%d",&key[i]);
}
CreateAVL(&T,key,num);
inorder(T);
printf("input a key to delete:");
scanf("%d",&n);
DeleteAVL(&T,n,shorter);
inorder(T);
return 0;
}
平衡二叉树
最新推荐文章于 2024-07-13 23:05:26 发布
本文详细介绍了AVL树的基本概念及实现方法,包括左旋、右旋、平衡处理等核心算法,并提供了完整的AVL树插入、删除操作的C语言代码实现。

2万+

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



