AVL

性质:

  • 1.AVL树是一棵二叉查找树
  • 2.对于其任意结点,其 左子树右子树 的高度之差(平衡因子)的绝对值不超过1

定义初始化:

struct node
{
    int data;
    int height;//当前子树高度
    node *lchild;
    node *rchild;
};
node* newnode(int v)
{
    node* Node=new node;
    Node->data=v;
    Node->lchild=Node->rchild=NULL;
    Node->height=1;//结点高度初始化为1
    return Node;
}

要计算平衡因子总的知道它的左右子树的高度,再计算

int getheight(node* root)
{
    if(root==NULL)
        return 0;
    return root->height;
}
int getbalancefactor(node* root)
{
    return getheight(root->lchild)-getheight(root->rchild);
}

完了,左旋右旋之后要更新你的结点高度

void updateheight(node* root)
{
    root->height=max(getheight(root->lchild),getheight(root->rchild))+1;
}

插入操作:

进行左右旋,使其平衡因子<=1,看图写代码( * ^ ▽ ^ * )

左旋

20882701-19a80610dab5e283
左旋
void L(node* &root)
{
    node* temp=root->rchild;
    root->rchild=temp->lchild;
    temp->lchild=root;
    updateheight(root);
    updateheight(temp);
    root=temp;
}

右旋

20882701-9cf76ad497ec47e3
右旋
void R(node* &root)
{
    node* temp=root->lchild;
    root->lchild=temp->rchild;
    temp->rchild=root;
    updateheight(root);
    updateheight(temp);
    root=temp;
}

在理解左右旋的基础上可以进行插入操作了,因为是在原先的一棵平衡二叉树上进行的操作,所以插入操作一定在底层的两棵子树上,对于插入操作,插入后会出现四种形态,LL,LR,RR,RL。

1.LL型(以A为根结点右旋)
20882701-a89db7f4f5ef65aa
image
2.LR型(先以C为根结点左旋,再以A为根结点右旋)
20882701-f31672bb7d387601
image
3.RR型(以A为根结点左旋)
20882701-9c6b30b3cdeb2ed8
image
4.RL型(先以C为根结点右旋,再以A为根结点左旋)

20882701-de6d39cc29db88e2
image

插入操作的代码块类似于二叉排序树的插入方式,每次插入完毕后 需要更新当前结点高度以及 调整成AVL形态

void Insert(node* &root,int v)
{
    if(root==NULL)
    {
        root=newnode(v);
        return;
    }
    if(v<root->data)
    {
        Insert(root->lchild,v);
        updateheight(root);
        if(getbalancefactor(root)==2)
        {
           if(getbalancefactor(root->lchild)==1)//LL
           {
               R(root);
           }
           else if(getbalancefactor(root->lchild)==-1)//LR
           {
               L(root->lchild);
               R(root);
           }
        }
    }
    else
    {
        Insert(root->rchild,v);
        updateheight(root);
        if(getbalancefactor(root)==-2)
        {
            if(getbalancefactor(root->rchild)==-1)//RR
            {
                L(root);
            }
            else if(getbalancefactor(root->rchild)==1)//RL
            {
                R(root->rchild);
                L(root);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值