JAVA数据结构与算法之————平衡二叉树

JAVA数据结构与算法之————平衡二叉树

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

本文将从以下几个方面进行介绍:

  1. TreeNode结构介绍。
  2. 向平衡二叉树中插入元素,然后调整二叉树使其仍然为平衡二叉树。
  3. 创建平衡二叉树。
  4. 删除平衡二叉树中的节点。

介绍TreeNode结构:
由于我在博客JAVA数据结构与算法之————二叉树中给出了TreeNode的结构,这里就不多重复了。

向平衡二叉树中插入元素,然后调整二叉树使其仍然为平衡二叉树:
向平衡二叉树中插入可能造成以下4种不平衡的情况:
1:如图1
在这里插入图片描述
节点5的平衡因子为2,所以应该进行右旋调整,调整后如图2:
在这里插入图片描述
具体实现过程看右旋代码(结合上图进行解释):

//    右旋操作

    public TreeNode<E> rightRotate(TreeNode<E> T) {
   
    
//    T为上图1中的节点5,p为节点3
        TreeNode<E> p = T.getlChild();
        
//    结点4作为结点5的左子树接入    
        T.setlChild(p.getrChild());
        
 //    结点5作为结点3的的右子树接入   
        p.setrChild(T);
//    如果结点4存在,则设置4的父节点为结点5
        if (T.getlChild() != null) {
   
            T.getlChild().setParent(T);
        }

//      让3变成5的父节点
        p.setParent(T.getParent());
        if (p.getParent() != null) {
   
            if (T == T.getParent().getlChild()) {
   
                p.getParent().setlChild(p);
            } else {
   
                p.getParent().setrChild(p);
            }

        }
        T.setParent(p);

        /*这里有一个需要注意的点是,要先跟新结点5的高度和平衡因子,在跟新结点3的*/
        T.setDepth(calDepth(T));
        T.setBalance(calBalance(T));

        p.setDepth(calDepth(p));
        p.setBalance(calBalance(p));

        return p;
    }

图1不平衡的二叉树经过右旋调整变成图2的平衡二叉树。

2,如图3
在这里插入图片描述
图3中2的平衡因子为-2,需要进行左旋操作,调整后如图4:
在这里插入图片描述
具体看代码(左旋和右旋类似):

//    左旋 ,基本和右旋类似
    public TreeNode<E> leftRotate(TreeNode<E> T) {
   
        TreeNode<E> p = T.getrChild();
        T.setrChild(p.getlChild());
        p.setlChild((T));

        if (T.getrChild() != null) {
   
            T.getrChild().setParent(T);
        }

        p.setParent(T.getParent());
        if (p.getParent() != null) {
   
            if (T == T.getParent().getlChild()) {
   
                p.getParent().setlChild(p);
            } else {
   
                p.getParent().setrChild(p);
            }

        }

        T.setParent(p);

        T.setDepth(calDepth(T));
        T.setBalance(calBalance(T));

        p.setDepth(calDepth(p));
        p.setBalance(calBalance(p));

        return p;
    }

3,如图5:
在这里插入图片描述
如图5,结点5的平衡因子为2,结点2的平衡因子为-1,它们的平衡因子符号相反,这种情况应该对根结点为2的子树进行左旋炒作,然后对根节点为5的子树进行右旋操作,调整后如图6:
在这里插入图片描述
4,如图7:
在这里插入图片描述
如图7,结点5的平衡因子为-2,结点2的平衡因子为1,它们的平衡因子符号相反,这种情况应该对根结点为5的子树进行右旋操作,然后对根节点为2的子树进行左旋操作,调整后如图8:
在这里插入图片描述
上代码:

public void adjust(TreeNode<E> T){
   
        //        如果T的平衡因子大于等于2,或者小于等于-2,,都需要对以T为跟节点的子树进行旋转调整
        if (T.getBalance() >= 2) {
   
//            当T的平衡因和T左子树的平衡因子符号相反,需要先对T的左子树进行左旋操作,再对T进行右旋操作
            if (T.getlChild().getBalance() == -1) {
   
                
                leftRotate(T.getlChild());
            }
            rightRotate(T);
        }
//        与T的平衡因子为2的情况相似,先对T的右子树进行右旋操作,再对T进行左旋操作
        if (T.getBalance() <= -2) {
   
            if (T.getrChild().getBalance() == 1) {
   

                rightRotate(T.getrChild());
            }
            leftRotate(T);
        }
    }

下面就正式进入插入代码:

/*
     *向平衡二叉树中插入元素
     *  */
    public void insert(TreeNode<E> T, E data) {
   
        //如果data小于T的值,进入T的左子树
        if (data.compareTo(T.getData()) < 0) {
   
            if (T.getlChild() != null) {
   
                //如果左子树不为空,这递归左子树
                insert(T.getlChild()
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值