AVL树:删除

删除:单旋

如果要删除T3下的节点,可以进行一次右旋操作,但要注意的是,如果T0,T1和T2下面都有节点,那么旋转操作过后,高度不变所以并不会失衡。但如果T0,T1存在,T2不存在,那么旋转之后此子树的高度会减少1,那么它的祖先就会失衡。所以 g经单旋调整后复衡,子树高度未必复原;更高的祖先仍可能失衡。因有失衡传播现象,可能需要做O(logn)次调整

 

删除:多旋

代码如下 

//AVL树在del之后进行rebalance操作,从插入节点的父节点开始,逐层向上遍历进行rebalance,直到遍历到根节点,由于树是平衡的,所以rebalance的时间复杂度是O(logn)。
void rebalance(AVLNode* a){
    setBalance(a);
    if(a->balance== -2){                   //如果左子树比右子树高2层,需要通过旋转来重新平衡
        if(a->left->balance <=0){          //如果左子节点的左子树比右子树高,则进行一次右旋;如果左子节点的右子树比左子树高,则先进行左旋,再进行右旋。
            a=turnRight(a);
        }else{
            a=turnLeftThenRight(a);
        }
    }else if(a->balance==2){       //如果右子树比左子树高2层,需要通过旋转来重新平衡
        if(a->right->balance>=0){       //如果右子节点的右子树比左子树高,则进行一次左旋;如果右子节点的右子树比左子树低,则先进行右旋,再进行左旋。
            a=turnLeft(a);
        }else{
            a=turnRightThenLeft(a);
        }
    }
    if(a->parent){
        rebalance(a->parent);
    }else{
        tree.root=a;
    }
}

 

void delnodeifhas1childornot(AVLNode* a){ // 在BST树的基础上加了rebalance操作
    if(a->parent==0){
        if(a->left){
            tree.root=a->left;
            a->left->parent=0;
        }else{
            tree.root=a->right;
            a->right->parent=0;
        }
    }else{
        if(a->parent->left==a){
            if(a->left){
                a->parent->left=a->left;
                a->left->parent=a->parent;
            }else{
                a->parent->left=a->right;
                if(a->right)
                    a->right->parent=a->parent;
            }
        }else{
            if(a->left){
                a->parent->right=a->left;
                a->left->parent=a->parent;
            }else{
                a->parent->right=a->right;
                if(a->right)
                    a->right->parent=a->parent;
            }
        }
        rebalance(a->parent);
    }
}
struct AVLNode* getmin(AVLNode* a){
    if(a->left)
        getmin(a->left);
    else
        return a;
} 
void delnodeifhas2child(AVLNode* a){
    AVLNode* after=getmin(a->right);
    a->value=after->value;
    delnodeifhas1childornot(after);
}
void del(int value,AVLNode* root){         //删除操作
    AVLNode* node=select(value,root);
    if(node->value==value){
        if(node->left&&node->right){
            delnodeifhas2child(node);
        }else{
            delnodeifhas1childornot(node);
        }
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值