AVL树的插入和删除

平衡二叉树定义:任一节点的左右子树高度差的绝对值不超过1。
定义BF为平衡因子,HL和HR分别为T的左右子树的高度,满足|BF|<=1。
节点数为n的平衡二叉树的最大高度为O(lgn)。
查找、插入和删除在平均和最坏情况下的时间复杂度都是
O(logn),增加和删除可能需要通过一次或多次树旋转来重新平衡这棵树。
在AVL树中插入一个节点的算法:
(1)若树为空,插入元素作为AVL树的根节点,树的深度增1
(2)若插入元素和根节点值相等,则不进行处理
(3)若插入元素的值小于根节点值,而且在左子树中不存在和插入元素相同的节点,则将元素插入该树的左子树,插入之后左子树的深度增加1,分别就下列不同情况处理:
a,根节点的平衡因子为-2(右子树的深度大于左子树深度,则将平衡因子调整为-1)
b,根节点的平衡因子为2(右子树的深度小于左子树深度,则将平衡因子调整为1)
(4)若插入元素的值大于根节点值,而且在右子树中不存在和插入元素相同的节点,则将元素插入该树的右子树,插入之后右子树的深度增加1,分别就不同情况进行处理。
AVL树的调整策略:
T1, T2, T3 , T4 子树
(1)插入点位于左子树的左子树

这里写图片描述

(2)插入点位于左子树的右子树

这里写图片描述

(3)插入点位于右子树的右子树

这里写图片描述

(4)插入点位于右子树的左子树

这里写图片描述

typedef struct ACLNode *Position;
typedef Position AVLTree;
struct AVLNode{
    ElementType Data;//节点数据
    AVLTree Left;//指向左子树
    AVLTree Right;//指向右子树
    int Height;//树高
};
int Max(int a, int b){
    return a>b ? a : b;
}
AVLTree SingleLeftRotation(AVLTree A){
//A必须有一个右子结点B
    AVLTree B = A->Right;
    AVLTree C = B->Left;
    B->Right = A;
    A->Left = C;
    A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
    B->Height = Max(GetHeight(B->Left), GetHeight(B->Right)) + 1;
    return B;
}
AVLTree SingleRightRotation(AVLTree A){
//A必须有一个左子结点B
    AVLTree B = A->Left;
    AVLTree C = B->Right;
    B->Right = A;
    A->Left = C;
    A->Height = Max(GetHeight(A->Left), GetHeight(A->Right))+1;
    B->Height = Max(GetHeight(B->Left), GetHeight(B->Right)) + 1;
    return B;
}
AVLTree DoubleLeftRightRotation(AVLTree A){
//A必须有一个左子结点B,且B必须有一个右子结点C,先左移,再右移
    A->Left = SingleLeftRotation(A->Left);
    return SingleRightRotation(A);
}
AVLTree DoubleRightLeftRotation(AVLTree A){
//A必须有一个右子结点B,且B必须有一个左子结点C,先右移,再左移
    A->Right = SingleRightRotation(A->Left);
    return SingleLeftRotation(A);
}
AVLTree Insert(AVLTree T, ElementType X) {
    if(!T) {
        T = (AVLTree)malloc(sizeof(struct AVLNode));
        T->Data = X;
        T->Height = 0;
        T->Left = T->Right = NULL;
    } else if(X < T->Data) {
        //插入左子树
        T->Left = Insert(T->Left, X);
        if (GetHeight(T->Left) - GetHeight(T->Right) == 2) {
            if (X < T->Left->Data){//右单旋
                T= SingleRightRotation(T);
            } else {
                T = DoubleLeftRightRotation(T);//左右旋转   
            }
        }
    } else if(X > T->Data) {
            //插入右子树
            T->Right = Insert(T->Right, X);
            if(GetHeight(T->Left) - GetHeight(T->Right) == -2) {
                if(X > T->Right->Data){
                    T = SingleLeftRotation()T;//左单旋 
                } else {
                    T = SingleRightLeftRotation(T);//右左单旋
                }   
            }
    }
    T->Height = Max(GetHeight(T->Left), GetHeight(T->Right));
    return T;
}

AVL树的删除元素同二叉查找树相同,需要删除后调整树的平衡因子,调整过程同插入元素后的调整方式相同。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值