avl树的插入操作和删除操作

https://blog.csdn.net/Faded0104/article/details/75042985

avl树相比于搜索二叉树每个结点是多了个平衡因子bf,avl树时时刻刻要维持树中的每个结点的平衡因子的绝对值小于等于1.

avl树的插入操作

avl树因为要保证每个结点的平衡因子要时时刻刻都符合要求,则树中每插入一个结点,都可能引起平衡被打破,所以每次插入一个结点,都要从插入的结点往上进行检查是否有哪个结点需要调整. 要在插入新结点后进行平衡检查,则需要把插入结点的插入过程的下行路线上的每一个结点都依次记录下来,这个可以借助于栈来实现,在查找插入位置的过程,把每一个结点指针放入栈中.

现在来说一下具体的过程:

1.从根结点开始,首先查找要插入的位置:

如果结点值相等则返回错误,如果小于则向左走,如果大于则向右走,把这个过程中的每一个结点都放入一个栈中,这样直到到达叶子结点,即找到了插入的位置.然后new出来一个结点进行插入(如果这个位置的父亲结点(stack中的top)是NULL,则是空树,让root指针指向该结点,插入完成,如果父亲结点不是NULL,则根据父亲结点和本结点的值的大小确定是左边插入还是右边插入).

2.插入完成以后进行平衡调整:

取出栈中的元素进行检查:插入的结点对于取出的结点如果是左边插入,则平衡因子减1,如果右边插入则平衡因子加1.

如果加减1以后平衡因子是0,即意味着插入节点之前平衡因子只能是正负1,插入该节点以后,该子树的左右子树高度相等,因此并不改变该子树的高度,也就并不影响整棵树的高度,所以树是平衡的,不需要调整,调整结束,break ;

如果平衡因子是+1或者-1,则意味着该节点所在的子树的高度发生变化,(因为在此之前该节点的平衡因子只能是0),所以以该节点为root 的子树的高度一定是增加了,所以要向上继续检查是否有哪个节点的平衡因子因为插入了一个节点平衡因子变为正负2,所以继续取出stack中的下一个节点进行上述同样的检查;

如果平衡因子是正负2,则平衡打破,需要进行调整。

3.下面详述调整过程

根据平衡子是+2还是-2分为两种情况:

(1).平衡因子是-2:
如果该节点的孩子节点平衡因子是负值:则对该节点进行一次左旋转即调整完成;

如该该节点的孩子节点的平衡因子是正值:则需要进行先孩子节点左旋后该节点右旋转.

(2).平衡因子是+2:

如果该孩子节点bf 是正值:则对该节点进行一次右旋转即可;

如果孩子节点bf是负值:则对该节点进行先右孩子节点后该节点左旋转即可.

调整平衡完成以后需要将该子树的新根节点挂到之前的该节点的父节点下面.由于调整之后树高就减少一层,抵消了插入节点带来的树高增加一层的变化,即调整完成,不需要继续向上检查.

AVL树的删除操作

1.首先查找要删除的节点,找到以后,要删除的节点分为两种情况:

(1).要删除的节点左右两个孩子都存在,直接删除不方便,则在右子树中查找最小的节点,将其值替换为要删除的节点的值,因为右子树的最小节点必然没有左孩子,即只有一个孩子.然后问题转化为删除这个右子树中最小的节点.(或者也可以将问题转化为删除左子树里最大的节点)

(2).要删除的孩子节点只有一个孩子节点.

以上均为要删除的节点只有一个孩子节点,则直接将仅有的一个孩子节点提上来即可.

2.删除以后将进行从删除节点向上进行平衡性的检查:(在查找要删除的节点的过程中,将经过的路径上的节点全部存放到一个stack)

栈->取出栈顶元素pr并弹出栈顶元素,如果删除的节点x比该节点pr的值小,则必定是左树删除,则pr的平衡因子pr->bf–否则pr->bf++.

(1).如果pr->bf的绝对值是1:则在删除节点之前,pr的bf是0,即左右平衡,删除了以后左树或者右树少了一个节点,但pr这个子树的高度并没发生变化.对与pr的上面的所有节点而言树高并没有发生变化,所以调整完成.

(2).如果平衡因子变为0:则在删除之前平衡因子是+1或者-1,现在删除节点以后变为0,则pr子树的高度减1,则要向上继续检查,情况重新回到栈->上面去检查..

(3).如果平衡因子的绝对值是2:则平衡打破,进行平衡调整:

3.下面详细描述调整过程:(pr的孩子节点是p)
pr->bf>0(即+2)pr->bf<0((即-2))
p->bf > 0(即+1)pr右旋p先右旋后pr左旋
p->bf = 0pr右旋pr左旋
p->bf < 0(即-1)p左旋后pr右旋pr左旋

调整完成之后,还需要对pr子树调整完后的新的子树根节点做平衡性检查,因为调整的时候有可能会使pr子树减少一层,所以需要继续向上检查.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值