数据结构之平衡二叉树、AVL树

AVL 树

二叉搜索树的性能问题

在二叉搜索树中的查找和删除操作的时间复杂度是 o(h)级别的,可见二叉搜索树的高度直接影响了二叉搜索树的使用性能,但是随着不断的添加和删除操作,二叉搜索树的左右子树高度可能会存在差距太大的情况,所以在删除和添加之后应该对二叉搜索树进行调整,使用最小的调整次数把二叉搜索树调整为左右子树高度相近。

二叉搜索树的问题

在添加、删除元素过程中二叉树可能会退化为链表,下面举例说明

  • 添加

    • 在添加元素的时候安装升序或者降序来添加元素。
  • 删除

    • 在对BST树元素删除的过程中,BST子树之间的高度差越来越大,影响BST树的性能。

平衡二叉搜索树

如果能够在对BST树删除和添加操作之后对BST子树之间的高度差进行检测,如果大于预计的值就对BST树进行调整使之子树之间的高度差减小,这样BST树就能一直保持着较高的效率了。

具体应用

  • AVL 树
  • 红黑树

AVL

基本概念

  • 平衡因子
    • 某个节点的左右子树的高度差
  • 每个节点的平衡因子只能是 1、-1 、0
    • 也就是每个节点的左右子树高度差不能超过1
      • 如果节点的平衡因子超过 1 就是失衡的状态
  • 搜索、添加、删除的时间复杂度是 O(logN)

导致失衡的原因

添加导致的失衡

AVL树的调整

  • LL 右旋转 (单旋)
  • RR 左旋转 (单旋)
  • LR RL (双旋转)

具体的实现

  • 添加节点导致的失衡
    • 从添加的这个节点开始找,开始调整所有失衡节点中高度最低的那个节点
    • 只要是高度最低节点重新回复平衡,那么整个树也就恢复了。
举例

约定:

  • 失去平衡高度最低的那个节点叫做 grand节点
  • 失去平衡且高度最低的那个节点的最高子节点叫做 parent节点
  • 新添加的节点叫做 node节点
RR 左旋转

思路

此时是13这个节点出现了不平衡,需要对它进行旋转操作。选择操作达成的效果就是让 13 这个节点向左旋转一下,对于树的操作而言:

  • 调整13这个节点的右子树为 14节点的左子树
  • 调整14这个节点的左子树为13
  • 把14节点的父节点调整为13节点的父节点。
  • 调整 13 节点的父节点
  • 调整 14 节点左子树的父节点

Code

grand.right = parent.left
parent.left.parent = grand
grand.parent = parent
parent.parent = grand.parent
parent.left = grand
LL 右旋转

思路

此时是13这个节点出现了不平衡,需要对它进行旋转操作。选择操作达成的效果就是让 13 这个节点向右旋转一下,对于树的操作而言:

  • 调整13这个节点的左子树为 12节点的右子树
  • 调整12这个节点的左子树为13
  • 把12节点的父节点调整为13节点的父节点
  • 调整 11 节点的父节点
  • 调整 12 右子树的父节点

Code

grand.left = parent.right
parent.right.parent = grand
grand.parent = patent
parent.parent = grand.parent
parent.right = grand
LR 双旋转

在这里插入图片描述

思路

此时是 16 节点出现了不平衡,然后对于16节点来说恢复平衡的方案是进行两次旋转,13左旋转之后 15右旋转,对于树的操作而言:

  • 13左旋

    • 13 节点的右子树 设置为 15节点的左子树
    • 调整 15 节点左子树的父节点
    • 15 节点的左子树 设置为 13节点
    • 16 节点的左子树 设置为 15节点
    • 调整 15节点的父节点
    • 调整 13 节点的父节点
  • 15右旋

    • 16 节点的左子树 设置为 15节点的右子树
    • 调整 15节点右子树的父节点
    • 15 节点的右子树 设置为 16节点
    • 调整 16 节点的父节点
    • 15 节点的父节点 设置为 16节点的父节点

Code

参考 左右旋转
RL 双旋转

在这里插入图片描述

思路

此时是 13 节点出现了不平衡,然后对于13节点来说恢复平衡的方案是进行两次旋转,15右旋转之后 13左旋转,对于树的操作而言:

  • 15右旋

    • 15 节点的左子树 设置为 14节点的右子树
    • 调整 14节点右子树的父节点
    • 14 节点的右子树 设置为 15节点
    • 调整15节点的父节点
    • 13 节点的右子树 设置为 14节点
    • 调整 14 节点的父节点
  • 13左旋

    • 13 节点的右子树 设置为 14节点的左子树
    • 14 节点的父节点 设置为 13节点的父节点
    • 14 节点的左子树 设置为 13节点
    • 调整 1 节点左子树的父节点
    • 调整 13 节点的父节点

Code

参考 左右旋转
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值