AVL算法分析

一、何为AVL平衡树?
具有以下特点:
1.二叉查找树结构(左孩子结点 < 父结点 < 右孩子结点)
2.结点左右两边的高度差(平衡因子balance)为[-1,1]
=> balance = | Deep(LeftChild) - Deep(RightChild)| <= 1
3.失衡:balance > 1
==> balance == 2 ==> 左平衡(Deep(LeftChild)-Deep(RightChild) == 2)
balance < -1
==> balance == -2 ==> 右平衡(Deep(LeftChild)-Deep(RightChild) == -2)
二、AVL平衡树----插入结点

  • 左平衡
    在这里插入图片描述

  • 右平衡
    在这里插入图片描述

public class AviTree1<T extends Comparable<T>> implements ITreeFactory<T> {

private TreeNode<T> mRoot;

private final int EQ = 0;
private final int EL = 1;
private final int ER = -1;


@Override
public TreeNode<T> generaTree(T[] arrays) {
    arrays = Arrays.copyOf(arrays,arrays.length);
    for (T t : arrays){
        insertTree(mRoot,t);
        printTreeNode(mRoot);
        System.out.println("");
    }
    return mRoot;
}

private void insertTree(TreeNode<T> parent,T data){

    TreeNode<T> node = createTreeNode(data);
    if(mRoot == null){
        mRoot = node;
    }else {
        int com = parent.compareTo(data);
        if(com == 0) return;
        if(com > 0){
            if(parent.left != null){
                insertTree(parent.left,data);
            }else {
                parent.left = node;
                node.parent = parent;

                adjustTreeStruct(node);
            }
        }else {
            if(parent.right != null){
                insertTree(parent.right,data);
            }else {
                parent.right = node;
                node.parent = parent;
                adjustTreeStruct(node);
            }
        }
    }
}

private void printTreeNode(TreeNode root){
    if(root == null) return;

    System.out.print(root.value +" , " );
    printTreeNode(root.left);
    printTreeNode(root.right);
}

private TreeNode<T> getBalanceRootNode(TreeNode<T> node){

    TreeNode<T> parent = node.parent;
    while (parent != null){
        if(parent.compareTo(node.value) > 0){
            parent.weight++;
        }else {
            parent.weight--;
        }
        if(Math.abs(parent.weight)>=2){
            break;
        }
        parent = parent.parent;
    }

    return parent;
}

private void adjustTreeStruct(TreeNode<T> node){
    TreeNode<T> parent = getBalanceRootNode(node);
    if(parent == null) return;
    switch (parent.weight){
        case 2:
            leftAdjust(parent);
            break;
        case -2:
            rightAdjust(parent);
            break;
    }

}

private void leftAdjust(
        TreeNode<T> parent){
    TreeNode<T> left = parent.left;
    TreeNode<T> right = parent.right;


    //1.parent 一个子节点   parent left lLeft 结点  -> parent右旋    parent.weight = left.weight = 0
    //2.parent 一个子节点   parent left lRight 结点  -> 先right左旋后parent右旋   parent.weight = left.weight = 0

    //3.parent 两个子节点  left 两个子节点(注意以parent为根,且parent有两个结点时,left必须只有2个结点,否则parent就会下移为left)
    //3.1 left.weight > 0   -> parent右旋 parent.weight = left.weight = 0;

    //3.2 left.weight < 0  leftChild.weight > 0  -> 先left左旋 后parent右旋  lRight.weight = left.weight = 0   parent.weight=-1
    //3.3 left.weight < 0  leftChild.weight < 0  -> 先left左旋 后parent右旋  lRight.weight = parent.weight = 0   left.weight=1


    if(right == null || left.weight >0){
        if(left.weight < 0){
            leftRotate(left);
        }
        rightRotate(parent);
        parent.weight = EQ;
        left.weight = EQ;

    }else {
        TreeNode<T> leftChild = left.right;
        if(leftChild.weight > 0){
            parent.weight = ER;
            leftChild.weight = EQ;
            left.weight = EQ;
        }else {
            parent.weight = EQ;
            left.weight = EL;
            leftChild.weight = EQ;
        }
        leftRotate(left);
        rightRotate(parent);
    }
}

private void rightAdjust(
        TreeNode<T> parent){
    TreeNode<T> right = parent.right;
    TreeNode<T> left = parent.left;

    if(left == null || right.weight<0){
        if(right.weight > 0){
            rightRotate(right);
        }
        leftRotate(parent);
        parent.weight = EQ;
        right.weight = EQ;
    }else {
        TreeNode<T> rightChild = right.left;
        if(rightChild.weight < 0){
            parent.weight = EL;
            right.weight = EQ;
            rightChild.weight = EQ;
        }else {
            parent.weight = EQ;
            right.weight = ER;
            rightChild.weight = EQ;
        }
        rightRotate(right);
        leftRotate(parent);
    }

}

private TreeNode<T> createTreeNode(T data){
    TreeNode<T> node = new TreeNode<>();
    node.value = data;
    node.weight=0;
    return node;
}

private void leftRotate(TreeNode<T> root){

    TreeNode<T> parent = root.parent;
    TreeNode<T> right = root.right;
    TreeNode<T> rLeft = right.left;

    right.parent = parent;
    if(parent != null){
        if(parent.compareTo(right.value)>0){
            parent.left = right;
        }else {
            parent.right = right;
        }
    }else {
        mRoot = right;
    }
    root.right = rLeft;
    if(rLeft != null){
        rLeft.parent = parent;
    }

    root.parent = right;
    right.left = root;
}

private void rightRotate(TreeNode<T> root){

    TreeNode<T> parent = root.parent;
    TreeNode<T> left = root.left;
    TreeNode<T> lRight = left.right;

    left.parent = parent;
    if(parent != null){
        if(parent.compareTo(left.value)>0){
            parent.left = left;
        }else {
            parent.right = left;
        }
    }else {
        mRoot = left;
    }
    root.left = lRight;
    if(lRight != null){
        lRight.parent = root;
    }

    root.parent = left;
    left.right = root;
}

}

源码-下面是文件路径
java_base/src/main/java/com/zy/java_base/arithmetic/tree/avl/AviTree1.java

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值