Java实现AVL(平衡二叉树)

本文详细介绍了AVL树的实现方法,包括节点的定义、插入、删除操作及旋转调整,确保树的平衡,提高了查找效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



class AVLNode<T extends Comparable<T>>{
    private T data;
    private AVLNode<T> left;
    private AVLNode<T> right;
    private int height; // 记录节点当前的高度值

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

    public T getData() {
        return data;
    }

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

    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;
    }

    public int getHeight() {
        return height;
    }

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

/**
 * 描述:
 * @Date 2019/7/3
 */
public class AVL<T extends Comparable<T>> {
    private AVLNode<T> root;

    private AVL(){
        this.root = null;
    }

    /**
     * 以参数node为根节点进行左旋操作,把旋转后的树的根节点返回
     * @param node
     * @return
     */
    private AVLNode<T> leftRotate(AVLNode<T> node){
        AVLNode<T> child = node.getRight();
        node.setRight(child.getLeft());
        child.setLeft(node);

        //更新结点的高度
        node.setHeight(maxHeight(node.getLeft(),node.getRight())+1);
        child.setHeight(maxHeight(child.getLeft(),child.getRight())+1);

        return child;
    }
/*----------------------------------------------------------------------------------------------------------------------------------------*/

    /**
     * 以参数node为根节点进行右旋操作,把旋转后的树的根节点返回
     * @param node
     * @return
     */
    private AVLNode<T> rightRotate(AVLNode<T> node){
        AVLNode<T> child = node.getLeft();
        node.setLeft(child.getRight());
        child.setRight(node);

        //更新结点的高度
        node.setHeight(maxHeight(node.getLeft(),node.getRight())+1);
        child.setHeight(maxHeight(child.getLeft(),child.getRight())+1);

        return child;
    }

/*----------------------------------------------------------------------------------------------------------------------------------------*/

    /**
     * 节点的高度
     **/
    private int maxHeight(AVLNode<T> left, AVLNode<T> right) {
        int l = height(left);
        int r = height(right);
        return l > r ? 1 : r;
    }

    private int height(AVLNode<T> root) {
        return root == null ? 0: root.getHeight();
    }

/*----------------------------------------------------------------------------------------------------------------------------------------*/

    /**
     * 以参数node为根节点进行左平衡操作,把旋转后的树的根节点返回
     * 左-右旋转
     * @param node
     * @return
     */
    private AVLNode<T> leftBalance(AVLNode<T> node){
        node.setLeft(leftRotate(node.getLeft()));   //先以根节点的左孩子为根节点左旋,更新一下根节点的左孩子
        return rightRotate(node); //以更新后的根节点进行右旋
    }

/*----------------------------------------------------------------------------------------------------------------------------------------*/
    /**
     * 以参数node为根节点进行右平衡操作,把旋转后的树的根节点返回
     * 右-左旋
     * @param node
     * @return
     */
    private AVLNode<T> rightBalance(AVLNode<T> node){
        node.setRight(rightRotate(node.getRight()));  //先以根节点的右孩子为根节点右旋,更新一下根节点的右孩子
        return leftRotate(node);
    }

/*----------------------------------------------------------------------------------------------------------------------------------------*/
    /**
     * 以参数node为起始节点,搜索一个合适的位置添加data,再把子树的根节点返回
     * 递归实现AVL树的插入操作
     * @param data
     * @return AVLNode<T>
     */
    public void insert(T data){
        this.root = insert(this.root,data);
    }

    private AVLNode<T> insert(AVLNode<T> root,T data) {

        if (root == null) {
            return new AVLNode<>(data, null, null, 1);
        }

        if (root.getData().compareTo(data) > 0) {
            root.setLeft(insert(root.getLeft(), data));
            //判断root节点是否失衡
            if (height(root.getLeft()) - height(root.getRight()) > 1) { //左 > 右 失衡
                //左孩子的左子树太高,右旋
                if (height(root.getLeft().getLeft()) >= height(root.getLeft().getRight())) {
                    root = rightRotate(root);
                } else {
                    //左孩子的右子树太高,左平衡
                    root = leftBalance(root);
                }
            }
        } else if (root.getData().compareTo(data) < 0) {
            root.setRight(insert(root.getRight(), data));
            //判断root节点是否失衡
            if (height(root.getRight()) - height(root.getLeft()) > 1) { //右 > 左 失衡
                   //右孩子的右子树太高,右旋
                if (height(root.getRight().getRight()) >= height(root.getRight().getLeft())) {
                    root = leftRotate(root);
                } else {
                    //右孩子的左子树太高,右平衡
                    root = rightBalance(root);
                }
            }
        }
        //递归回溯的过程中,更新节点的高度值
        root.setHeight(maxHeight(root.getLeft(), root.getRight()) + 1);
         return root;
        }

/*----------------------------------------------------------------------------------------------------------------------------------------*/
    /**
     * AVL树的递归删除操作
     * @param data
     * */
        public void remove(T data){
            this.root = remove(this.root,data);
        }

       private AVLNode<T> remove(AVLNode<T> root, T data) {
           if (root == null) {
               return null;
           }
           if (root.getData().compareTo(data) > 0) {  //在左边找
               root.setLeft(remove(root.getLeft(), data));

               //判断root节点是否失衡
               if (height(root.getLeft()) - height(root.getRight()) > 1) { //左 > 右 失衡
                   //左孩子的左子树太高,右旋
                   if (height(root.getLeft().getLeft()) >= height(root.getLeft().getRight())) {
                       root = rightRotate(root);
                   } else {
                       //左孩子的右子树太高,左平衡
                       root = leftBalance(root);
                   }
               }
           } else if (root.getData().compareTo(data) < 0) {
               root.setRight(insert(root.getRight(), data));
               //判断root节点是否失衡
               if (height(root.getRight()) - height(root.getLeft()) > 1) { //右 > 左 失衡
                   //右孩子的右子树太高,右旋
                   if (height(root.getRight().getRight()) >= height(root.getRight().getLeft())) {
                       root = leftRotate(root);
                   } else {
                       //右孩子的左子树太高,右平衡
                       root = rightBalance(root);
                   }
               }
           } else if (root.getData().compareTo(data) < 0) {  //在右边找
               root.setRight(remove(root.getRight(), data));
           } else {
               if (root.getLeft() != null && root.getRight() != null) {
                   if(height(root.getLeft()) >= height(root.getRight())){  //左大于右 高度
                       //用前驱替换
                       AVLNode<T> pre = root.getLeft();
                       while (pre.getRight() != null) {
                           pre = pre.getRight();
                       }
                       root.setData(pre.getData());
                       root.setLeft(remove(root.getLeft(), pre.getData())); //删除前驱
                   }else {
                       //用后继替换
                       AVLNode<T> post = root.getRight();
                       if (root.getLeft() != null) {
                           post = post.getRight();
                       }
                       root.setData(post.getData());
                       root.setRight(remove(root.getRight(),post.getData())); //删除后继
                   }
               }else{
                   if(root.getLeft() != null){
                       return root.getLeft();
                   }else if(root.getRight() != null){
                       return root.getRight();
                   }else {
                       return null;
                   }
               }
           }

           return root;
       }



       public static void main(String[] args) {
        AVL<Integer> avl = new AVL<>();
        for(int i = 1; i < 11; i++){
            avl.insert(i);
        }
     }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值