AVL树C++实现

平衡二叉树定义:平衡二叉树是二叉排序树,其中每个节点的左子树和右子树的高度至多等于1.

平衡二叉树是两位俄罗斯科学家(G.M.Adelson-Velskill and E.M.Landis)与1962年一种解决平衡二叉树的算法所以又叫做AVL树

平衡二叉树的实现原理:在构建二叉排序树的过程中保证每一次的插入节点,首先,寻找做小不平衡子树。在保证二叉排序树特性的情况下,通过旋转最小不平衡子树使之成为新的平衡二叉树。

实现过程,

在每个节点中加入平衡因子。bf 用1,0,-1分别表示左子树的高度减去右子树的高度

如果出现自小不平衡子树时一定是下列清空之一。其中最N表示新节点


 AE的操作是对称的可以通过一次旋转得到平衡二叉树。需要调整两个节点的平衡因子。对于BC和FG也是对称的需要经过两次旋转得到AVL树。此时需要调整三个节点的平衡因子。


具体的调节过程如图以ABC为例


具体的代码如下:

#include<iostream>
using namespace std;
typedef struct BiTNode
{
    int data;
    int bf;
    struct BiTNode *lchild,*rchild;

}BiTNode,*BiTree;
/*
向右旋转P所指向的二叉树 不调整平衡因子
*/
void R_Rotate(BiTree *P)
{
    BiTree L;
    L = (*P)->lchild;
    (*P)->lchild=L->rchild;
    L->rchild=(*P);
    *P=L;
}

/*
向左旋转P所指向的二叉树 不调整平衡因子
*/
void L_Rotate(BiTree *P)
{
    BiTree R;
    R= (*P)->rchild;
    (*P)->rchild=R->lchild;
    (R->lchild)=(*P);
    (*P)=R;
}

const int LH = +1;
const int EH = 0;
const int RH = -1;
/*
如果最小不平衡树T是由于新的节点插入在T的左子树上就进行做做平衡调整
输入参数指向最不平衡子树指针的指针
*/
void LeftBlance(BiTree *T)
{
    BiTree L,Lr;
    L = (*T)->lchild;
    switch(L->bf)
    {
        case LH:
            //插入发生在L的左子树上属于情况A
            L->bf=(*T)->bf=EH;
            R_Rotate(T);
           // cout<<"abc";
            break;
        case RH:
            Lr = L->rchild;
            switch (Lr->bf)
            {
                case LH:
                    //情况B
                    Lr->bf=EH;
                    L->bf=EH;
                    (*T)->bf=RH;
                    L_Rotate(&((*T)->lchild));
                    R_Rotate(T);
                    break;
                case EH:
                    //该种请款出现在叶子节点上
                    Lr->bf=EH;
                    L->bf=EH;
                    (*T)->bf=EH;
                    L_Rotate(&((*T)->lchild));
                    R_Rotate(T);
                    break;
                case RH:
                    //情况C
                    Lr->bf=EH;
                    L->bf=LH;
                    (*T)->bf=EH;
                    L_Rotate(&((*T)->lchild));
                    R_Rotate(T);
                    break;
            }
    }
}
/*
如果最小不平衡树T是由于新的节点插入在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 EH:
            break;
        case LH:
            RL = R->lchild;
            switch (RL->bf)
            {
                case EH:
                    (*T)->bf=RL->bf=R->bf=EH;
                    R_Rotate(&((*T)->rchild));
                    L_Rotate(T);
                    break;
                case LH:
                    RL->bf=EH;
                    (*T)->bf=EH;
                    R->bf = RH;
                    R_Rotate(&((*T)->rchild));
                    L_Rotate(T);
                    break;
                case RH:
                    RL->bf=EH;
                    (*T)->bf=LH;
                    R->bf = EH;
                    R_Rotate(&((*T)->rchild));
                    L_Rotate(T);
                    break;
            }
            break;
    }
}
void printL(BiTree tree)
{
    if(NULL == tree)
        return;
        cout<<tree->data<< " ";
    printL(tree->lchild);
    printL(tree->rchild);
}
bool InSertData(BiTree *tree,int *taller,int data)
{

    if(NULL==(*tree))
    {
        *taller =1;
        BiTree newnode=(BiTree)malloc(sizeof(BiTNode));
        newnode->bf=0;
        newnode->lchild=newnode->rchild=NULL;
        newnode->data=data;
        *tree=newnode;
        return true;
    }
    if((*tree)->data==data)
    return false;
    if((*tree)->data>data)
    {
        bool suc = InSertData(&((*tree)->lchild),taller,data);
        if(!suc)
            return false;
        if(1== *taller)
        {
            switch ((*tree)->bf)
            {
                case LH:
                    *taller =0;
                    LeftBlance(tree);
                    break;
                case EH:
                    (*tree)->bf=LH;
                    *taller = 1;
                    break;
                case RH:
                    (*tree)->bf=EH;
                    *taller = 0;
                    break;
            }
        }
        return true;
    }
    else
    {
        //将数据插入到右子树上
        if(!InSertData(&((*tree)->rchild),taller,data))
            return false;
        if(1 == *taller)
        {
            switch((*tree)->bf)
            {
                case LH:
                    (*tree)->bf = EH;
                    *taller = 0;
                    break;
                case EH:
                    (*tree)->bf = RH;
                    *taller = 1;
                    break;
                case RH:
                    RightBalance(tree);
                     *taller = 0;
                    break;
            }
        }
        return true;
    }

}

int main()
{
    int i;
   int a[10] = { 3,2,1,4,5,6,7,10,9,8};
   // int a[10] = { 4,5,6,7,10,9,8};
    BiTree T=NULL;
    int taller =0;
    for (i =0;i<10;i++)
    {
        InSertData(&T,&taller,a[i]);

        cout<<a[i]<<" ";
        printL(T);
        cout<<endl;
    }
    //printL(T);
    return 1;
}



转载于:https://my.oschina.net/u/2322146/blog/406245

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值