AVL树的概念及其四种旋转操作的实现

平衡二叉树(AVL树)的四种旋转操作的实现:

关于为什么要使用平衡二叉树,我们首先举个例子来说明BST树存在的问题:
在这里插入图片描述
如上图,给你一个数列[10,20,30,40],创建一颗二叉排序树(BST),我们就上图来分析BST树存在的问题:
1.左子树全部为空,从形式上来看,像是一个单链表
2.插入速度没有影响
3.查询速度降低(因为类似于这样的BST树,在查询时,不仅要依次比较,不能发挥BST树的优势,每次还需要比较左子树,查询速度比单链表还慢)
如何解决BST树存在的此类问题呢?
解决方案:使用平衡二叉树(AVL)

平衡二叉树(AVL树)的概念及其使用

AVL = BST +平衡
平衡:节点的左右子树的高度差不超过1
平衡二叉树(AVL):

1.AVL树节点的类型

/**
 * AVL树的节点类型
 * @param <T>
 */
class AVLNode<T extends Comparable<T>>{
    private T data;
    private int height; //用来记录当前节点的高度
    private AVLNode<T> left;
    private AVLNode<T> right;

    public AVLNode(T data, int height) {
        this.data = data;
        this.height = height;
        this.left=this.right=null;
    }

    public AVLNode(T data, int height, AVLNode<T> left, AVLNode<T> right) {
        this.data = data;
        this.height = height;
        this.left = left;
        this.right = right;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public AVLNode<T> getLeft() {
        return left;
    }

    public void setLeft(AVLNode<T> left) {
        this.left = left;
    }

    public AVLNode<T> getRight() {
        return right;
    }

    public void setRight(AVLNode<T> right) {
        this.right = right;
    }

2.AVL树的建立

/**
     * AVL树的类定义
     */
    class AVL<T extends Comparable<T>>{
        private AVLNode<T> root;
        public AVL(){
             this.root=null;
        }
        /**
         * 获取节点node的左右子树高度差
         */
        public int height(AVLNode<T> node){
            return node ==null?0:node.getHeight();
        }
        /***
         * 返回当前节点左右子树的高度最高值
         */
        public int maxHeight(AVLNode<T> left,AVLNode<T> right){
           return height(left)>height(right)?height(left):height(right);
        }

3.AVL树的左旋操作

 /**
         *                    node      20
         * AVL树的左旋操作     child           30              ===》        30
         *                                x         50                20        50
         * 右孩子的右子树太高
         */
        private AVLNode<T> rotateLeft(AVLNode<T> node){
            AVLNode<T> child = node.getRight();
            //以孩子节点为根节点进行左旋操作
            node.setRight(child.getLeft());
            //将孩子节点的右孩子设为node节点的左孩子
            child.setLeft(node);
            //将node节点设为孩子节点的左孩子
            node.setHeight(maxHeight(node.getLeft(),node.getRight())+1);
            //更新以node节点为根节点的AVL树的高度
            child.setHeight(maxHeight(child.getLeft(),child.getRight())+1);
            //更新以child节点为根节点的AVL树的高度
            return child;
            //把旋转后的根节点返回
        }

4.AVL树的右旋操作的实现

 /**                             node     40                  20
         * AVL树的右旋操作             child     20     ==》       10      40
         * 左孩子的左子树太高                  10    x                    x
         */
        private AVLNode<T> rotateRight(AVLNode<T> node){
            AVLNode<T> child = node.getLeft();
            //1.以child孩子为根节点,进行右旋操作
            node.setLeft(child.getRight());
            //将孩子节点的右孩子作为node节点的左孩子
            child.setRight(node);
            //将node节点设为孩子节点的右孩子
            node.setHeight(maxHeight(node.getLeft(),node.getRight())+1);
            //更新以node节点为根节点的AVL树的高度
            child.setHeight(maxHeight(child.getLeft(),child.getRight())+1);
            //更新以child节点为根节点的AVL树的高度
            return child;
            //把旋转后的根节点返回
        }

5.AVL树的左-右旋转(左平衡)

 /**
         * AVL树的(左平衡)左--右旋转    40    左旋       40  右旋     30
         *                            20      ===》  30    =====》20     40
         * 左孩子的右子树太高             30        20
         *
         * 先以20为根节点进行左旋转,再以30为根节点进行右旋转
         */
         private AVLNode<T> leftBalance(AVLNode<T> node){
             node.setLeft(rotateLeft(node.getLeft()));
             return rotateRight(node);
         }

6.AVL树的右-左旋转(右平衡)

/**
         * AVL树的右平衡 右--左旋转20     右旋     20    左旋       30
         *                           40 =====》     30 =====》 20    40
         * 右孩子的左子树过高       30                  40
         *
         * 先以40为根节点进行右旋转,再以30为根节点进行左旋转
         */
          private AVLNode<T> rightBalance(AVLNode<T> node){
              node.setRight(rotateRight(node.getRight()));
              return rotateLeft(node);
          }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值