AVL树

AVL 树,平衡二叉树,相比与二叉搜索树来说,多了一个平衡因子,该成员可以帮助二叉树进行自我平衡的调整

private:
Type data;
AVLNode *leftChild;
AVLNode *rightChild;
int bf;

那么,bf到底代表了什么含义呢,对每一个结点来说,它的平衡因子bf就是它的子树高度与右树高度差的绝对值,在二叉平衡树中,每插入一个新的结点,就要看一下它结点的平衡因子是否大于1,或者是否小于-1,当平衡因子的绝对值比1大时,就要进行平衡化调整。

而对于平衡化的调整,有以下几种情况(画术不精,望请见谅,以下四副图按顺序为1,2,3,4)


这四种情况就代表了要进行平衡化调整的四种情况

1.进行右旋转

2.先进行左旋转,在进行一次右旋转

3.进行一次左旋转

4.先进性一次右旋转在进行一次左旋转

下面我们对这四种情况的旋转分别进行简单描述:

(1)右旋转,在我的理解上就是,单进行一次旋转的情况,如图一图三,就是一条道走的太黑,所以我们要把它往它不愿意去的那边掰弯,让它平衡,均衡发展,它往左偏,就把它往右掰,它往右偏,就把它往左边掰,以图一为例,旋转时将该子树的根节点转下来,作为它左孩子的右子树,平衡因子随之做相应调整,左旋转同理

(2)双旋转,以图二为例,要先做一次左旋转,在做一次右旋转,偏的不正常,就像走了一半弯路的想要从弯路的中间折回去,这肯定是不对的,要先回到你原本的弯路上,在做相应调整,如图二,左旋转就对它下面的两个结点进行调整,且对调了身份,父为子,子为父,接下来就像是回到了图一,在进行一次右旋转就好了

以上都是在不考虑中间结点没有其他结点的情况下,如果中间结点存在其他子树,比如右转,就要将其他子树取下来连接在被旋转下来结点的左子树上,可能说的不是太清楚,直接上代码,四种情况的旋转在代码中有具体的体现。

AVLNode<Type>* RotateL(AVLNode<Type> *&ptr)
{
AVLNode<Type> *subL = ptr;
ptr = subL->rightChild;
subL->rightChild = ptr->leftChild;
ptr->leftChild = subL;
ptr->bf = subL->bf = 0;
return ptr;
}
AVLNode<Type>* RotateR(AVLNode<Type> *&ptr)
{
AVLNode<Type> *subR = ptr;
ptr = subR->leftChild;
subR->leftChild = ptr->rightChild;
ptr->rightChild = subR;
ptr->bf = subR->bf = 0;
return ptr;
}
AVLNode<Type>* RotateLR(AVLNode<Type> *&ptr)
{
AVLNode<Type> *subR = ptr;
AVLNode<Type> *subL = ptr->leftChild;
ptr = subL->rightChild;

subL->rightChild = ptr->leftChild;
ptr->leftChild = subL;
//bf
if(ptr->bf <= 0)
subL->bf = 0;
else
subL->bf = -1;

subR->leftChild = ptr->rightChild;
ptr->rightChild = subR;
//bf
if(ptr->bf >= 0)
subR->bf = 0;
else
subR->bf = 1;


ptr->bf = 0;
return ptr;
}
AVLNode<Type>* RotateRL(AVLNode<Type> *&ptr)
{
AVLNode<Type> *subL = ptr;
AVLNode<Type> *subR = ptr->rightChild;
ptr = subR->leftChild;
subR->leftChild = ptr->rightChild;
ptr->rightChild = subR;
//bf
if(ptr->bf >= 0)
subR->bf = 0;
else
subR->bf = 1;


subL->rightChild = ptr->leftChild;
ptr->leftChild = subL;
//bf
if(ptr->bf <= 0)
subL->bf = 0;
else
subL->bf = -1;


ptr->bf = 0;
return ptr;
}
private:
AVLNode<Type> *root;
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值