图解平衡二叉树(AVL树)

二叉搜索树(BST)存在的问题
我们先把{1,2,3,4,5,6}这颗二叉搜索树创建出来,结果如下图:
在这里插入图片描述
可以看出这颗而擦搜索树的左子树全部为空,看起来更像一个单链表.
此时它的插入速度没有影响,但查询速度明显降低(因为需要依次比较,所以时间复杂度变为O(n)), 不能发挥BST的优势,而且因为每次还需要比较左子树,其查询速度比单链表还慢。

为了解决以上问题于是主角登场了------平衡二叉树(AVL)

平衡二叉树(AVL)

概念平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树, 可以保证查询效率较高。

特点:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树

非平衡二叉树转平衡二叉树
左旋转
根据数组 {4,3,6,5,7,8}创建出对应的平衡二叉树。
在这里插入图片描述
步骤
1.创建一个新的节点newNode,值等于当前根节点的值
2.把新节点的左子树设置为当前节点的左子树newNode.left=left;
3.把新节点的右子树设置为当前节点的右子树的左子树newNode.right=right.left;
4.把当前节点的值换为右子节点的值value=right.value;
5.把当前节点的右子树设置成右子树的右子树right=right.right;
6.把当前节点的左子树设置为新节点left=newNode;

代码:

public void leftRotate(){
   
      //1.创建一个新的节点`newNode`,值等于当前根节点的值
       Node newNode=new Node(value);
       // 2.把新节点的右子树子树设置为当前节点的右子树
        newNode.right=right;
      //  3.把新节点的左子树设置为当前节点的左子树的右子树
        newNode.left=left.right;
      //  4.把当前节点的值换为左子节点的值
        value=left.value;
      //  5.把当前节点的左子树设置成左子树的左子树
        left=left.left;
      //  6.把当前节点的右子树设置为新节点
        right=newNode;
    }

右旋转
根据数组{10,12, 8, 9, 7, 6}创建出对应的平衡二叉树。
在这里插入图片描述
步骤:
1.创建一个新的节点newNode,值等于当前根节点的值
2.把新节点的右子树子树设置为当前节点的右子树newNode.right=right;
3.把新节点的左子树设置为当前节点的左子树的右子树newNode.left=left.right.;
4.把当前节点的值换为左子节点的值value=left.value;
5.把当前节点的左子树设置成左子树的左子树left=left.left;
6.把当前节点的右子树设置为新节点right=newNode;
代码:

//右旋转
    public void rightRotate(){
   
       //1.创建一个新的节点`newNode`,值等于当前根节点的值
        Node newNode=new Node(value);
      //  2.把新节点的左子树设置为当前节点的左子树
        newNode.left=left;
      //  3.把新节点的右子树设置为当前节点的右子树的左子树`
         newNode.right=right.left;
      //  4.把当前节点的值换为右子节点的值
        value=right.value;
      //  5.把当前节点的右子树设置成右子树的右子树
        right=right.right;
      //  6.把当前节点的左子树设置为新节点
        left=newNode;
    }

双旋转
上面的两个数组进行一次单旋转就可以吧非平衡二叉树转换成平衡二叉树,但某些数组不能经过一次单旋转就完成平衡二叉树,如{10,11,7,6,8,9},符合右旋转条件,右旋转后如下图,仍然是非平衡二叉树。
在这里插入图片描述
解决办法:当符合右旋转的条件时,如果她的右子树高度大于它的左子树高度,先对当前这个节点的左节点进行左旋转,然后再对当前节点进行右旋转。
在这里插入图片描述
完整代码实现:


public class AVLTreeDemo {
   
    public static void main(String[] args) {
   
        int array[]={
   10,11,7,6,8,9};
        //创建一个AVLTree对象
        AVLTree avlTree=new AVLTree();
        //添加节点
        for(int i=0;i<array.length;i++){
   
            avlTree.add(new Node(array[i]));
        }

        //遍历
        System.out.println("中序遍历");
        avlTree.infixOrder();

        System.out.println("转换为平衡二叉树后");
        System.out.println("树的高度="+avlTree.getRoot().height());
        System.out
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值