avl树的完整实现

public class AVLTree<T> {
    AvlNode<T> root;//树根
    public void insert(int key,T value){
        root = insert(root,key,value);
    }
    public AvlNode<T> insert(AvlNode<T> node,int key,T value){
        //没有节点就创建节点
        if(node == null){
            node = new AvlNode<T>(key, value);
            updateBalanceFactor(node);
            return node;
        }
        if(key < node.key){
            //递归的寻找可以插入的节点,如果键比当前节点的键小,就继续递归的寻找
            node.leftChild = insert(node.leftChild, key, value);
            //插入操作后检查平衡因子
            updateBalanceFactor(node);
            //检查当前的平衡因子,如果平衡因子大于1,就说明左支过重了,因为是递归插入,只会有左支过重,所以不会有右支过重
            if(node.balanceFactor > 1){
                //如果左孩子的平衡因子大于1,就说明左边的节点比又变多,就是左左类型,要使用右单旋,否则就是用左右双旋
                if(node.leftChild.balanceFactor > 0){
                    node = rightRotate(node);
                }else{
                    node =leftRightRotate(node);
                }
            }
        }else if(key > node.key){
            //递归的寻找可以插入的节点,如果键比当前节点的键大,就继续递归的寻找
            node.rightChild = insert(node.rightChild, key, value);
            //插入操作后检查平衡因子
            updateBalanceFactor(node);
            if(node.balanceFactor < -1){
                //如果当前节点的右孩子的平衡因子小于-1,就说明右支过重了
                if(node.balanceFactor < -1){
                    //如果当前节点的右孩子的平衡因子小于0,就说明是右右类型,就左单旋,否则就右左双旋
                    if(node.rightChild.balanceFactor < 0){
                        node = leftRotate(node);
                    }else{
                        node = rightLeftRotate(node);
                    }
                }
            }
        }
        //跟新平衡因子,并返回节点
        updateBalanceFactor(node);
        return node;
    }
    public void delete(int key){
        root = delete(root, key);
    }
    private AvlNode<T> delete(AvlNode<T> node,int key){
        if(node == null){
            return node;
        }
        //如果值小于当前节点的值就递归下去继续删
        if(key < node.key){
            //递归查询左节点,删除后返回完整的左支
            node.leftChild = delete(node.leftChild, key);
            updateBalanceFactor(node);
            //如果递归删除后树不平衡了,就要旋转节点
            if(node.balanceFactor > 1 ){
                if(node.leftChild.balanceFactor > 0){
                    node = rightRotate(node);
                }else{
                    node = leftRightRotate(node);
                }
            }else if(node.balanceFactor < -1){
                if(node.rightChild.balanceFactor < 0){
                    node = leftRotate(node);
                }else{
                    node = rightLeftRotate(node);
                }
            }
        //如果值大于当前节点的值就递归下去继续删
        }else if(key > node.key){
            node.rightChild = delete(node.rightChild, key);
            updateBalanceFactor(node);
            //删除后不平衡就旋转节点
            if(node.balanceFactor > 1 ){
                if(node.leftChild.balanceFactor > 0){
                    node = rightRotate(node);
                }else{
                    node = leftRightRotate(node);
                }
            }else if(node.balanceFactor < -1){
                if(node.rightChild.balanceFactor < 0){
                    node = leftRotate(node);
                }else{
                    node = rightLeftRotate(node);
                }
            }
        //如果找到了要删除的节点,并且节点左右儿子都不为空
        }else if(node.leftChild != null && node.rightChild != null){
            //判断平衡因子,不能加剧失衡,替换为多的哪一支
            if(node.balanceFactor > 1){
                //左支更深,用左支最大的节点替换
                AvlNode<T> max = max(node.leftChild);
                node.key = max.key;
                node.data = max.data;
                //递归找到并删除节点,因为是递归思想,所以默认删除后获取的节点都是平衡的
                node.leftChild = delete(node.leftChild, max.key);
                //操作后更新平衡因子
            }else{
                //否则就拿右节点中最大的节点替换
                AvlNode<T> min = min(node.rightChild);
                node.key = min.key;
                node.data = min.data;
                node.rightChild = delete(node.rightChild,min.key);
            }
            //更新平衡因子,如果不平衡就旋转节点
            updateBalanceFactor(node);
            if(node.balanceFactor > 1 ){
                if(node.leftChild.balanceFactor > 0){
                    node = rightRotate(node);
                }else{
                    node = leftRightRotate(node);
                }
            }else if(node.balanceFactor < -1){
                if(node.rightChild.balanceFactor < 0){
                    node = leftRotate(node);
                }else{
                    node = rightLeftRotate(node);
                }
            }
        }else{
            //删除叶节点或者只有一个儿子的节点,因为avl树定义,所以无论如何删除都不会引起本层的不平衡。
            node = node.rightChild !=null ? node.rightChild:node.leftChild;
            return node;
        }
        updateBalanceFactor(node);
        return node;
    }
    /** * 更新平衡因子 * @param node */
    private void updateBalanceFactor(AvlNode<T> node){
        //左子树的深度
        int liftChildHight = getHight(node.leftChild);
        //右子树的深度
        int rightChildHight = getHight(node.rightChild);
        //更新树深
        node.hight = Math.max(liftChildHight, rightChildHight) + 1;
        //平衡因子为左子树的深度-右子树的深度
        node.balanceFactor = liftChildHight - rightChildHight;
    }
    /** * 右重,左单旋 */
    private AvlNode<T> leftRotate(AvlNode<T> node){
        //新节点树,就是之前的右孩子节点
        AvlNode<T> newNode = node.rightChild;
        //拿右孩子左补自己的右
        node.rightChild = newNode.leftChild;
        //拿自己补孩子的左
        newNode.leftChild = node;
        //更新节点平衡因子
        updateBalanceFactor(node);
        updateBalanceFactor(newNode);
        //返回旋转后的节点
        return newNode;
    }
    /** * 左重,右单旋 * @param node * @return */
    private AvlNode<T> rightRotate(AvlNode<T> node){
        //新节点树,之前的左节点
        AvlNode<T> newNode = node.leftChild;
        //拿左孩子的右孩子补自己的左节点
        node.leftChild = newNode.rightChild;
        //拿自己补孩子的右节点
        newNode.rightChild = node;
        updateBalanceFactor(node);
        updateBalanceFactor(newNode);
        return newNode;
    }
    /** * 右重,右左双旋,先孩子右,后自己左 * @param node * @return */
    private AvlNode<T> rightLeftRotate(AvlNode<T> node){
        //孩子右旋,自己左旋
        node.rightChild = rightRotate(node.rightChild);
        return leftRotate(node);

    }
    /** * 左重,左右双旋,先孩子左,后自己右 * @param node * @return */
    private AvlNode<T> leftRightRotate(AvlNode<T> node){
        node.leftChild = leftRotate(node.leftChild);
        return rightRotate(node);
    }
    /** * 求树高 * @param node * @return */
    private int getHight(AvlNode<T> node){
        return node == null?0:node.hight;
    }
    /** * 获最小的一个节点 * @param node * @return */
    private AvlNode<T> min(AvlNode<T> node){
        if(node == null){
            return null;
        }else if(node.leftChild == null){
            return node;
        }
        return min(node.leftChild);
    }
    /** * 中序遍历 * @param node */

    /** * 获取最大的一个节点 * @param node * @return */
    private AvlNode<T> max(AvlNode<T> node){
        if(node == null){
            return null;
        }else if(node.rightChild == null){
            return node;
        }
        return max(node.rightChild);
    }
    /** * 中序遍历 * @param node */
    public void middleOrder(AvlNode<T> node){
        if(node == null){
            return ;
        }
        middleOrder(node.leftChild);
        System.out.println("key:"+node.key+",vlaue:"+node.data);
        middleOrder(node.rightChild);
    }
    /** * avl树节点 * @author yuli * * @param <T> */
    private static class AvlNode <T>{
        int key;
        T data;
        int hight;//树的高度
        int balanceFactor;//平衡因子,左子树的高度-右子树的高度,只能为1,0,-1
        AvlNode<T> leftChild;//左子树
        AvlNode<T> rightChild;//右子树
        AvlNode(int key,T data){
            this.key = key;
            this.data = data;
        }
    }
}
    原文作者:AVL树
    原文地址: https://blog.csdn.net/yulio1234/article/details/77493902
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞