平衡二叉树AVL

AVL树详解

#include <iostream>

using namespace std;

//平衡二叉树节点
typedef struct BiTNode
{
    int value,height;
    struct BiTNode *left,*right;
}BiTNode,*AVL;

//获得以root为根节点的子树的当前heighr
int GetHeight(BiTNode *root)
{
    if(root==NULL)
        return 0;
    return root->height;
}

//计算节点root的平衡因子
int getBalanceFactor(BiTNode *root)
{
    return GetHeight(root->left)-GetHeight(root->right);
}

//更新root节点的height
void updateheight(BiTNode *root)
{
    root->height=(GetHeight(root->left)>GetHeight(root->right)?GetHeight(root->left):GetHeight(root->right))+1;
}

//遍历AVL树
void Tranverse_AVL(BiTNode *root)
{
   if(root!=NULL)
   {
       Tranverse_AVL(root->left);
       cout<<root->value<<" "<<root->height<<endl;
       Tranverse_AVL(root->right);
   }
}

//发现以root为根的树的最小值点
BiTNode *FindMin(BiTNode *root)
{
    if(root!=NULL)
    {
        while(root->left!=NULL)
            root=root->left;
    }
    return root;
}

//发现以root为根的树的最大值点
BiTNode *FindMax(BiTNode *root)
{
    if(root!=NULL)
    {
        while(root->right!=NULL)
            root=root->right;
    }
    return root;
}

//left_rotation操作
void left_rotation(AVL &root)  //要特别注意先更新哪个高度,画图自己了解
{
    BiTNode *tmp=root->right;
    root->right=tmp->left;
    tmp->left=root;
    updateheight(root);
    updateheight(tmp);
    root=tmp;
}

//right_rotation操作
void right_rotation(AVL &root)     //要特别注意先更新哪个高度,画图自己了解
{
    BiTNode *tmp=root->left;
    root->left=tmp->right;
    tmp->right=root;
    updateheight(root);
    updateheight(tmp);
    root=tmp;
}

//注意我们有左旋和右旋,2种操作,有LL,LR,RL,RR四种树形。其中的两种树形分别对应左旋和右旋操作
//剩下的2种树形可以通过组合左右旋操作,形成 left_rotation,right_rotation,left_right_rotation,right_left_rotation
//如果BF(root)==2,BF(root->left)==1,对root进行 right_rotation操作,对应LL
//如果BF(root)==2,BF(root->left)==-1,先对root->left进行左旋,再对root进行右旋,即left_right_rotation,对应LR
//如果BF(root)==-2,BF(root->right)==-1,对root进行左旋,left_rotation,对应RR
//如果BF(root)==-2,BF(root->right)==1,先对root->right进行右旋,再对root进行左旋,right_left_rotation,对应RL

//left_right_rotation
void left_right_rotation(AVL &root)
{
    left_rotation(root->left);
    right_rotation(root);
}

//right_left_rotation
void right_left_rotation(AVL &root)
{
    right_rotation(root->right);
    left_rotation(root);
}


void insert_AVL(AVL &root,int v)
{
    if(root==NULL)
    {
        BiTNode *tmp=new BiTNode;
        tmp->value=v;
        tmp->left=NULL;
        tmp->right=NULL;
        tmp->height=1;
        root=tmp;
        cout<<"节点"<<v<<"插入成功!"<<endl;
        return;
    }

    else if(v<root->value)
    {
        insert_AVL(root->left,v);
        updateheight(root);
        if(getBalanceFactor(root)==2)
        {
            if(getBalanceFactor(root->left)==1)
                right_rotation(root);
            else if(getBalanceFactor(root->left)==-1)
            {
                //left_rotation(root->left);
                //right_rotation(root);
                left_right_rotation(root);
            }
        }
    }

    else if(v>root->value)
    {
        insert_AVL(root->right,v);
        updateheight(root);
        if(getBalanceFactor(root)==-2)
        {
            if(getBalanceFactor(root->right)==-1)
                left_rotation(root);
            else if(getBalanceFactor(root->right)==1)
            {
                //right_rotation(root->right);
                //left_rotation(root);
                right_left_rotation(root);
            }
        }
    }
    else
        return;
}

//删除节点
void delete_node(AVL &root,int v)
{
    if(root==NULL)
        return;
    if(v<root->value)
    {
        delete_node(root->left,v);   //从左子树里边删除节点
        if((GetHeight(root->right)-GetHeight(root->left))==2)
        {
            BiTNode *tmp=root->right;
            if(GetHeight(tmp->right)>GetHeight(tmp->left))    //RR型,需要左旋即可
                left_rotation(root);
            else     //RL型   右左旋
                right_left_rotation(root);

        }
    }
    if(v>root->value)
    {
        delete_node(root->right,v);
        if((GetHeight(root->left)-GetHeight(root->right))==2)
        {
            BiTNode *tmp=root->left;
            if(GetHeight(tmp->left)>GetHeight(tmp->right))   //LL型,右旋即可
                right_rotation(root);
            else   //LR型,   左右旋
                left_right_rotation(root);
        }
    }
    else   //v==root->value
    {
        if(root->left==NULL&&root->right==NULL)
        {
            delete root;
            root=NULL;
        }
        else
        {
            if(root->left)  //左子树不为空
            {
                BiTNode *pre=FindMax(root->left);
                root->value=pre->value;
                delete_node(root->left,pre->value);
                updateheight(root);
            }
            else //右子树不为空
            {
                BiTNode *next=FindMin(root->right);
                root->value=next->value;
                delete_node(root->right,next->value);
                updateheight(root);
            }
        }
    }
}

//构建AVL树
AVL Create_AVL(int data[],int n)
{
   BiTNode *root=NULL;
   for(int i=0;i<n;i++)
   {
       insert_AVL(root,data[i]);
   }
   cout<<"构建二叉树成功!"<<endl;
   return root;
}

int main()
{
    int data[8]={3,7,2,5,9,1,4,6};
    AVL root=Create_AVL(data,8);
    Tranverse_AVL(root);

    cout<<endl;

    delete_node(root,7);
    Tranverse_AVL(root);
    return 0;
}

删除节点不是很成功,貌似没有旋转和调整高度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值