java实现AVL树

一.各种二叉树比较

1.满二叉树

一个二叉树,每层节点都能达到最大值,即若一颗高度为h的二叉树,其节点个数为2^h-1

2.完全二叉树

若二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树

3.平衡二叉树(AVL树)

在完全二叉树的基础上实现二叉排序树

二叉排序树

二.问题引出

我们知道,数组元素创建二叉排序树时,数组第0个为根节点

例:int[] arr = {1,2,3,4,5,6};

这样构建的二叉排序树就是一个链表,这样会增加检索时间,降低效率

若把该二叉树转成AVL树则会大大提高检索效率

三.解决方案

将二叉排序树左旋转或右旋转,以达到该二叉排序树成为完全二叉树的特点

这里以该数组为例,右子树较高,故左旋

左旋步骤如下

1.创建一个新节点node,值为当前根节点的值

2.新节点的左子节点为根节点的左子节点

3.新节点的右子节点设置为根节点右子节点的左子节

4.根节点的值设为右子节点的值

5.根节点的右子节点设为右子节点的右子节点

6.根节点的左子节点设为新节点

class AVLTree{
    public static int getHeight(TreeNode root){
        //求以root为根节点树的高度
        if(root == null)
            return 0;
        return Math.max(getHeight(root.left),getHeight(root.right))+1;
    }
    public static void Rotate(TreeNode root){
        //旋转

        //右大于左
        if(getHeight(root.right)-getHeight(root.left)>1){
            if(root.right!=null&&getHeight(root.right.left)>getHeight(root.right.right)){
                rightRotate(root.right);
            }
            leftRotate(root);
        }
        //左大于右
        else if(getHeight(root.left)-getHeight(root.right)>1){

            if(root.left!=null&&getHeight(root.left.left)<getHeight(root.left.right)){
                //提前旋转一次
                leftRotate(root.left);
            }
            rightRotate(root);
        }
    }

    public static void leftRotate(TreeNode root){//左旋
        //1.创建一个新节点node,值为当前根节点的值
        TreeNode node = new TreeNode(root.val);
        //2.新节点的左子节点为根节点的左子节点
        node.left = root.left;
        //3.新节点的右子节点设置为根节点右子节点的左子节
        node.right = root.right.left;
        //4.根节点的值设为右子节点的值
        root.val = root.right.val;
        //5.根节点的右子节点设为右子节点的右子节点
        root.right = root.right.right;
        //6.根节点的左子节点设为新节点
        root.left = node;
    }
    public static void rightRotate(TreeNode root){//右旋
        TreeNode node = new TreeNode(root.val);
        node.right = root.right;
        node.left = root.left.right;
        root.val = root.left.val;
        root.left = root.left.left;
        root.right = node;
    }
}
class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(){}
    TreeNode(int val){
        this.val = val;
    }

}

二叉树是对称的,故右旋就是左旋的反过来

这里还有一个注意的点

在左旋和右旋之前,得判断一下根节点左子树和右子树的高度

以int[] arr = {10,11,7,6,8,9};为例

不管左旋还是右旋都无法形成AVL树

在右旋前应该判断左子树的左右子树,如果其右子树高度大于左子树的高度,则先将根节点的左子树进行左旋,然后再将整棵树右旋

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值