平衡二叉树的创建

重点在于指针的运用

//平衡二叉树又称AVL树
//AVL树性质:左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1
#include <stdio.h>
#include <stdlib.h>
#define LH 1   //左子树高1
#define EH 0   //左、右子树等高
#define RH -1  //右子树高1
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int Boolean;

typedef struct BSTNode
{
    int data;
    int bf;
    struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;

int EQ(int a,int b);
int LT(int a,int b);
void R_Rotate(BSTree *T);
void L_Rotate(BSTree *T);
void LeftBalance(BSTree *T);
void RightBalance(BSTree *T);
Status InsertAVL(BSTree *T,int e,Boolean *taller);
int main()
{
    BSTree *T;
	T=(BSTree *)malloc(sizeof(BSTree));
	*T=NULL;
    
    int e;
    Boolean *taller;
	taller=(int *)malloc(sizeof(int));
    
    printf("请输入要插入的数--输入0退出:");
    scanf("%d",&e);
    while(e)
	{
		InsertAVL(T,e,taller);
		printf("请输入要插入的数--输入0退出:");
		scanf("%d",&e);
	}
    return 0;
}
//若在平衡的二叉排序树T中不存在和e有相同关键字的结点,则插入一个数据元素为e的新结点
//并返回1,否则返回0.若因插入而使二叉排序树失去平衡,则作平衡旋转处理
//布尔变量taller反映T长高与否
Status InsertAVL(BSTree *T,int e,Boolean *taller)
{
    if(!(*T))		//如果是空树,则分配空间,生成根结点
    {
		BSTree p;
		p=(BSTree )malloc(sizeof(BSTNode));
        p->data=e;
        p->lchild=p->rchild=NULL;
        p->bf=EH;
        *taller=TRUE;
		*T=p;
    }
    else
    {
        if(EQ(e,(*T)->data))
        {
            *taller=FALSE;
            return 0;
        }
        if(LT(e,(*T)->data))   //如果小于当前结点,则插入左子树
        {
            if(!InsertAVL(&(*T)->lchild,e,taller))
                return 0;            //如果左子树插入失败,则结束,如果插入成功,则往下继续
            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 0;
            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 1;
}

//由于在T的左子树根结点的左子树上插入结点,使T的平衡因子由1增至2而失去平衡
//则需进行一次右旋
void R_Rotate(BSTree *T)
{
    BSTNode *lc;
    lc=(BSTNode *)malloc(sizeof(BSTNode));

    lc=(*T)->lchild;
    (*T)->lchild=lc->rchild;
    lc->rchild=(*T);
    (*T)=lc;
}
//由于在T的右子树根结点的右子树上插入结点,使T的平衡因子由-1增至-2而失去平衡
//则需进行一次左旋
void L_Rotate(BSTree *T)
{
    BSTNode *rc;
    rc=(BSTNode *)malloc(sizeof(BSTNode));

    rc=(*T)->rchild;
    (*T)->rchild=rc->lchild;
    rc->lchild=(*T);
    (*T)=rc;
}
void LeftBalance(BSTree *T)
{
    BSTNode *lc,*rd;
    lc=(BSTNode *)malloc(sizeof(BSTNode));
    rd=(BSTNode *)malloc(sizeof(BSTNode));

    lc=(*T)->lchild;
    switch(lc->bf)
    {
        case LH:     //如果左子树是左高,则一定是插入在左子树的左子树才会导致失衡
            (*T)->bf=lc->bf=EH;
            R_Rotate(T);  //因此需要进行右旋
            break;
        case RH:     //如果左子树是右高,则一定是插入在左子树的右子树才会导致失衡
            rd=lc->rchild;    //左子树的右子树
            switch(rd->bf)
            {
                case LH:       //如果左子树的右子树是左高,则是插入在左子树的右子树的左子树
                    (*T)->bf=RH;  //则旋转后,根结点将会是右高
                    lc->bf=EH; //左子树结点将会是等高
                    break;
                case EH:        //如果是等高,则
                    (*T)->bf=lc->bf=EH;
                    break;
                case RH:
                    (*T)->bf=EH;
                    lc->bf=LH;
                    break;
            }
            rd->bf=EH;
            L_Rotate(&(*T)->lchild);
            R_Rotate(T);
    }
}
void RightBalance(BSTree *T)
{
    BSTNode *rc,*rd;
    rc=(BSTNode *)malloc(sizeof(BSTNode));
    rd=(BSTNode *)malloc(sizeof(BSTNode));

    rc=(*T)->rchild;
    switch(rc->bf)
    {
        case RH:     //如果右子树是右高,则一定是插入在右子树的右子树才会导致失衡
            (*T)->bf=rc->bf=EH;
            L_Rotate(T);  //因此需要进行左旋
            break;
        case LH:     //如果右子树是左高,则一定是插入在右子树的左子树才会导致失衡
            rd=rc->lchild;
            switch(rd->bf)
            {
                case LH:
                    (*T)->bf=EH;
                    rc->bf=RH;
                    break;
                case EH:
                    (*T)->bf=rc->bf=EH;
                    break;
                case RH:
                    (*T)->bf=RH;
                    rc->bf=EH;
                    break;
            }
            rd->bf=EH;
            R_Rotate(&(*T)->rchild);
            L_Rotate(T);
    }
}
int EQ(int a,int b)
{
	return a==b;
}
int LT(int a,int b)
{
	return a<b;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值