平衡二叉树(AVL树)

完整代码在最后。
教材里的左转右转也是看的一头雾水,画一下图就很明白了,不用去记左右旋转及其对应的情形,知道怎么变就行了。
picture1PICTURE2picture3Ppicture4

//
// Created by dgm on 19-4-10.
//
#include <iostream>
using namespace std;
#define LH 1
#define EH 0
#define RH -1

typedef char ElemType;
typedef struct BiNode{
    ElemType data;
    BiNode*lchild,*rchild;
    int bf;
}BiNode,*BiTree;

void L_Rotate_For_Left(BiTree&p)//the element is added to p->lchild->lchild
{
    auto lc=p->lchild;
    p->lchild=lc->rchild;
    lc->rchild=p;
    p=lc;
}

void R_Rotate_For_Right(BiTree&p)//the element is added to p->rchild->rchild
{
    auto rc=p->rchild;
    p->rchild=rc->lchild;
    rc->lchild=p;
    p=rc;
}

void R_Rotate_For_Left(BiTree&p)//the element is added to p->lchild->rchild
{
    auto lc=p->lchild;
    auto lcrc=lc->rchild;
    lc->rchild=lcrc->lchild;
    p->lchild=lcrc->rchild;
    lcrc->lchild=lc;
    lcrc->rchild=p;
    p=lcrc;
}

void L_Rotate_For_Right(BiTree&p)//the element is added to p->rchild->lchild
{
    auto rc=p->rchild;
    auto rclc=rc->lchild;
    p->rchild=rclc->lchild;
    rc->lchild=rclc->rchild;
    rc->lchild=p;
    rc->rchild=rc;
    p=rclc;
}

void LeftBalance(BiTree&T)      //when the new node was added to the left child of root(or T)
{
    auto lc=T->lchild;
    switch (lc->bf)
    {
        case LH:                //if it was added to T->lchild->lchild, just as picture1
            T->bf=lc->bf=EH;
            L_Rotate_For_Left(T);
            break;
        case RH:                //if it was added to T->lchild->lchild, just as picture2
            auto rc=lc->rchild;
            switch (rc->bf)
            {
                case LH:    //present T points to the new tree's right child after rotate, and lc points to left child
                            //as picture2 shows
                    T->bf=RH;lc->bf=EH;
                    break;
                case RH:     //the other situation of picture2
                    T->bf=EH;lc->bf=LH;
                    break;
            }
            rc->bf=EH;      //the root
            R_Rotate_For_Left(T); //after that, the old root T points to the new root;
            break;
    }
}

void RightBalance(BiTree&T)     //as above
{
    auto rc=T->rchild;
    switch (rc->bf)
    {
        case RH:
            R_Rotate_For_Right(T);
            T->bf=rc->bf=EH;
            break;
        case LH:
            auto lc=rc->lchild;
            switch (lc->bf)
            {
                case LH:
                    T->bf=EH;rc->bf=RH;
                    break;
                case RH:
                    T->bf=LH;rc->bf=EH;
                    break;
            }
            lc->bf=EH;
            L_Rotate_For_Right(T);
            break;
    }
}
bool InsertAVL(BiTree&T,ElemType e, bool&taller)
{
    if(!T){     //if the tree is null
        T=new BiNode();     //new a node
        T->data=e;
        T->lchild=T->rchild=NULL;
        T->bf=EH;
        taller= true;   //height be taller
    }
    else{
        if(T->data==e){     //the element was in the tree already
            taller= false;return 0; //not be taller
        }
        if(T->data>e) {     //added to left (elements in left is less than T)
            if (!InsertAVL(T->lchild, e, taller))return 0;  //already have
            if (taller) {       //add successfully
                switch (T->bf) {
                    case LH:    //added to left tree
                        LeftBalance(T); //...
                        taller = false; //the root is balanced
                        break;
                    case EH:    //notice it is added to T's left tree
                        T->bf = LH;  //so if T is balanced previously
                        taller = true;  //T's left tree will be taller
                        break;
                    case RH:    //T's right tree is taller previously
                        T->bf = EH;     //and the element is added to T's left tree
                        taller = false; //so it is equal in height
                        break;
                }
            }
        }
        else{       //as above
            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 true;
}

void CreateTree(BiTree&T,char arr[],int &index)  //create tree (or using InsertAVL)
{
    if(arr[index]=='#'){
        T=NULL;
    }
    else{
        T=new BiNode();
        T->data=arr[index];
        T->bf=EH;
        CreateTree(T->lchild,arr,++index);
        CreateTree(T->rchild,arr,++index);
    }
    return ;
}
//void PreTraverse(BiTree T)
//{
//    if(T)
//    {
//        cout<<T->data<<" ";
//        PreTraverse(T->lchild);
//        PreTraverse(T->rchild);
//    }
//}
int main()
{
    BiTree T;
    T=NULL;     //??如果不写这句T的值是多少,貌似默认不是NULL,因为不写这句就会出错,奇怪??
    bool taller= false;
    char arr[]="64##8##";   //也可以直接通过Insert来创建树
    int index=0;
    CreateTree(T,arr,index);    //左子树高,输出1
    cout<<T->bf<<endl;          //右子树高,输出-1
    InsertAVL(T,'3',taller);    //等高当然是输出0
    cout<<T->bf<<endl;
    InsertAVL(T,'5',taller);
    cout<<T->bf<<endl;
    InsertAVL(T,'2',taller);
    cout<<T->bf<<endl;
    InsertAVL(T,'9',taller);
    cout<<T->bf<<endl;
    cout<<"吆西yaoxi吆西"<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值