数据结构——AVL树的插入

#include <iostream>
using namespace std;

#define LH +1    //左高
#define EH 0    //等高
#define RH -1    //右高
#define false 0
#define true 1

typedef struct BSTNode
{
    int data;                    //节点的数据域
    int bf;                        //平衡因子
    BSTNode *lchild, *rchild;    //节点的左、右孩子指针
}BSTNode, * BSTree;                //将BSTree定义为结构体指针

//左旋转
void BSTree_L_Rotate(BSTree & root)                //root为需要旋转的子树树根指针 
{
    BSTree rc=root->rchild;                        //将rc指身树的树根的右子树
    root->rchild=rc->lchild;                    //将树的右子树的左子树挂到树根的右子树上
    rc->lchild=root;                            //将root所指树挂到rc的左子树上
    root=rc;                                    //更新树根
}

//右旋转
void BSTree_R_Rotate(BSTree & root)             //root为需要右旋的子树树根指针
{
    BSTree lc=root->lchild;                        //lc指向root的右子树根
    root->lchild=lc->rchild;                    //lc的右子树连接到root的左子树上
    lc->rchild =root;                            //root连接到lc的右子树
    root=lc;                                    //更新树根    
}

//左平衡处理
void LeftBalance(BSTree & root)     
{
    BSTree lc=root->lchild,rd=NULL;                //lc指向root的左子树
    switch(lc->bf)        
    {
        case  LH:    //LL型
        {
            /*    
             *        root--> *             *
             *               /            / \
             *        lc--> *        ==>    *   *
             *             /
             *            *
             */
            root->bf=lc->bf=EH;            //更新平衡因子
            BSTree_R_Rotate(root);        //root作为根进行 右 旋转
            break;
        }
        case RH:    //LR型
        {
            rd = lc->rchild;            //将rd指向lc的右子树
            switch(rd->bf)            //检查rd的平衡因子,并做相应的处理
            {
                case LH:
                {
                    root->bf = RH;    lc->bf = EH;    break;
                }
                case EH:
                {
                    root->bf = EH;    lc->bf = EH;    break;
                }
                case RH:
                {
                    root->bf = EH;    lc->bf = LH;    break;
                }
            }//switch(rd->bf)
            rd->bf = EH;

            BSTree_L_Rotate(root->lchild);    //以root的左子树根结点为根进行 左 旋转处理
            BSTree_R_Rotate(root);            //以root作为根进行 右 旋转处理
        }
    }//switch(lc->bf)
}//LeftBalance

//右平衡处理
void RightBalance(BSTree & root)       
{
     BSTree rc=root->rchild,ld=NULL;
     switch(rc->bf)                     
     {
         case RH:        //RR型
             {
                rc->bf=root->bf=EH;
                BSTree_L_Rotate(root);
             }
         case LH:        //RL型
             {
                ld=rc->lchild;
                switch(ld->bf)
                {
                    case LH:
                        {
                            root->bf=EH;    rc->bf=LH;        break;
                        }
                    case EH:
                        {
                            root->bf=EH;    rc->bf=EH;        break;
                        }
                    case RH:
                        {
                            root->bf=LH;    rc->bf=EH;        break;
                        }
                }//switch(ld->bf)
                ld->bf=EH;

                BSTree_R_Rotate(root->rchild);
                BSTree_L_Rotate(root);
             }
     }//switch(rc->bf)
}//RightBalance


//插入操作
int BSTree_Insert(BSTree &T, int taller, int data)   
{                                                       
     //now表示当前子树的根,taller为真时表示到目前为子树层数增加,为假则没增加
     //插入成功返回真,否则返回假
     if(!T)                                         //now指针为空时在当前指针处插入新节点
     {
        T=(BSTree)malloc(sizeof(BSTNode));        //新建一个节点
        T->bf=EH;            //节点初始化操作,平衡因子赋为0
        T->data=data;                    
        T->lchild=T->rchild=NULL;    
        taller=true;        //添加新节点,默认为增加子树的高度
        return true;        //插入成功,返回真
     }
     else
     {
             if(data == T->data)    //树中已存在和e相同的关键字结点,则不再插入
             {
                 taller=false;
                 return false;
             }
             else if(data < T->data)    //当前待插入数据小于当前子树根的数据
             {
                if( !BSTree_Insert(T->lchild, taller, data) )  //递归,以当前树根的左子树根为新子树树根调用插入函数
                    return  false;    //没有插入成功
                if(taller)     //判断taller的值,为真时插入操作一定成功,并且进入平衡处理                               
                {                                             
                    switch(T->bf)        //检查插入前当前树根的平衡因子
                    {
                    case RH:                           
                        {
                            T->bf=EH;        //原本右子树比左子树高,现在左右子树等高,无须进一步平衡处理,修改平衡因子即可
                            taller=false;    //子树高不改变,taller置为假
                            break;
                        }
                    case EH:
                        {
                            T->bf =LH;    //原本左右子树等高,插入后左子树高增加,但此子树的局部平衡没被破坏,修改平衡因子即可
                            taller=true;    //树高增加,taller置为真
                            break;
                        }
                    case LH:
                        {
                            LeftBalance(T);    //原本左子树就比右子树高,插入后此子树局部平衡被破坏,需调用左平衡处理函数使之平衡
                            taller=false;        //平衡处理后此子树高度不会增加,taller置为假
                            break;
                        }
                    }//switch(T->bf)
                }//if(taller)
             }//else if(data < T->data)

                else        //待插入数据大于当前子树根节点数据
                {
                    if( !BSTree_Insert(T->rchild,taller,data) )    //递归,以当前树根的右子树根为新子树树根调用插入函数
                        return false;    //没有插入成功
                    if(taller)
                    {
                        switch(T->bf)        //检查插入前当前树根的平衡因子
                        {
                        case RH:    
                            {
                                RightBalance(T);    //原本右子树就比左子树高,插入后此子树局部平衡被破坏,需调用右平衡处理函数使之平衡
                                taller=false;        //平衡处理后此子树高度不会增加,taller置为假
                            }
                        case EH:
                            {
                                T->bf=RH;        //原本左右子树等高,插入后左子树高增加,但此子树的局部平衡没被破坏,修改平衡因子即可
                                taller=true;    //树高增加,taller置为真
                            }
                        case LH:            
                            {
                                T->bf=EH;        //原本左子树就比右子树高,现在左右子树等高,无须进一步平衡处理,修改平衡因子即可
                                taller=false;    //子树高不改变,taller置为假
                            }
                        }//switch(T->bf)
                    }//if(taller)
                }//else
    }//else
    return true;                                       
}//BSTree_Insert

//中序遍历
void mind_Traverse(BSTree &root)
{
     if(root) 
     {
          mind_Traverse(root->lchild);          
          cout<<root->data<<"  ";            
          mind_Traverse(root->rchild);           
     }
}

//前序遍历
void pre_Traverse(BSTree &root)
{
     if(root) 
     {
          cout<<root->data<<"  ";
          pre_Traverse(root->lchild);         
          pre_Traverse(root->rchild);           
     }
}

int main()
{
    BSTree root;
    root=NULL;
    BSTree_Insert(root,0,34);
    BSTree_Insert(root,0,18);
    BSTree_Insert(root,0,13);
    BSTree_Insert(root,0,73);
    BSTree_Insert(root,0,16);
    BSTree_Insert(root,0,52);
    BSTree_Insert(root,0,58);
    BSTree_Insert(root,0,67);
    BSTree_Insert(root,0,82);
    BSTree_Insert(root,0,76);
    BSTree_Insert(root,0,93);
    
    mind_Traverse(root);
    cout<<endl;
    return 0;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

minyuanxiani

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值