AVL树(以及四种旋转的情况--Java实现)

首先AVL树也叫二叉平衡树,AVL树一定是BST树,那么为什么要引入AVL树呢?它比BST树好在哪儿呢?

BST树:BST树的增删改查,是从根节点出发找到叶子节点再进行操作的,时间复杂度为O(logn)

那么问题来了,如果你要插入的数据构成一个等差数列的话,比如{1,3,5,7,9}

BST树将会变成一个链表:

这样的话它的时间复杂度岂不是退化成O(n)了?查找某个元素时得遍历链表。

AVL树:在BST树的基础上引入了平衡的概念,也就是每个节点的左右孩子高度差不超过1。

平衡后的上面的BST树将是这样子的(经过两次右旋操作,一会儿解释这几种旋转操作):

AVL树的节点类型定义:

 static class Entry<T extends Comparable<T>>{
        private T data;
        private Entry<T> left;
        private Entry<T> right;
        private int high;//节点高度

        public Entry(){
            this(null,null,null,1);
        }


        public Entry(T data, int high) {
            this(data,null,null,1);
        }

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

---------------------------------------------------------------------------------------------------------------------------------

下面来介绍这四种旋转操作以及适用情况:

由于该节点的左孩子左子树太高,引起的失衡,需要进行右旋操作:

文字不太好叙述,直接画个图来解释:

实现右旋的代码:

 private Entry<T> rightRotate(Entry<T> node){
        Entry<T> child = node.left;
        node.left = child.right;
        child.right=node;
        //节点高度值更新
        node.high = maxHeight(node.left,node.right)+1;//旋转以后node为孩子节点
        child.high = maxHeight(child.left,child.right)+1;//旋转以后child为双亲节点
      return  child;
    }

---------------------------------------------------------------------------------------------------------------------

由于该节点的右孩子右子树太高,引起的失衡,需要进行左旋操作:

实现左旋的代码:

 private Entry<T> leftRotate(Entry<T> node){
   //左旋转
   Entry<T> child = node.right;
   node.right = child.left;
   child.left=node;
   //节点高度值更新
        node.high = maxHeight(node.left,node.right)+1;//旋转以后node为孩子节点
        child.high = maxHeight(child.left,child.right)+1;//旋转以后child为双亲节点
   return child;
    }

---------------------------------------------------------------------------------------------------------------------

由于该节点的左孩子右子树太高,引起的失衡,需要进行左平衡操作(先左旋再右旋):

左平衡操作的代码:

 public Entry<T> leftBalance(Entry<T> node){
     node.left = leftRotate(node.left); //先以左孩子为基准左旋转左子树
        return rightRotate(node);//再以根节点为基准右旋转
    }

---------------------------------------------------------------------------------------------------------------------

由于该节点的右孩子左子树太高,引起的失衡,需要进行右平衡操作(先右旋再左旋):

右平衡操作代码:

 public Entry<T> rightBalance(Entry<T> node){
        node.right = rightRotate(node.right); //先以右孩子为基准右旋转右子树
        return leftRotate(node);//再以根节点为基准左旋转
    }

---------------------------------------------------------------------------------------------------------------------

这四种旋转操作和AVL树的插入和删除操作息息相关,需要好好熟悉。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值