Avl 平衡二叉树 概念与代码实现

概念: 二叉树存在值顺序插入导致树高度过大的问题、平衡二叉树通过旋转的方式、使二叉树处于平衡状态、子树高度差不能大于1

旋转规则:

        左子树高右旋、右子树高左旋
        右旋时插入节点在最右、则子树先左旋
        左旋时插入节点在最左、则子树先右旋

代码实现: 

package com.info.dataStructure.avl;

/**
 * @author haizhuangbu
 * @date 2024/3/22 10:47
 * @mark AvlNode 节点
 */
public class AvlNode<T extends Comparable<T>> {

    AvlNode<T> left;

    AvlNode<T> right;

    T key;
    // 高度
    int height;

    public AvlNode(T key) {
        this.key = key;
        this.height = 0;
    }


}




package com.info.dataStructure.avl;

/**
 * @author haizhuangbu
 * @date 2024/3/22 10:45
 * @mark AvlTree
 */
public class AvlTree<T extends Comparable<T>> {

    // 根节点
    private AvlNode<T> root;


    public AvlTree() {
        this.root = null;
    }

    /**
     * @param node 节点
     * @return 节点高度(树的高度)
     */
    private int height(AvlNode<T> node) {
        if (node == null) return -1;
        return node.height;
    }

    private void updateHeight(AvlNode<T> node) {
        // 当前树的高度为 最大的子树高度 + 1
        node.height = Math.max(height(node.left), height(node.right)) + 1;
    }

    /**
     * @param avlNode 节点
     * @return 右旋
     */
    private AvlNode<T> rotateLeft(AvlNode<T> avlNode) {
        AvlNode<T> right = avlNode.right;
        avlNode.right = right.left;
        right.left = avlNode;
        updateHeight(avlNode);
        updateHeight(right);
        return right;
    }


    /**
     * @param node 节点
     * @return 右旋
     */
    private AvlNode<T> rotateRight(AvlNode<T> node) {
        AvlNode<T> left = node.left;
        node.left = left.right;
        left.right = node;
        updateHeight(node);
        updateHeight(left);
        return left;
    }


    private AvlNode<T> insert(AvlNode<T> node, T key) {
        if (node == null) return new AvlNode<>(key);
        // 将节点插入 平衡二叉树中
        if (key.compareTo(node.key) < 0) {
            node.left = insert(node.left, key);
        } else if (key.compareTo(node.key) > 0) {
            node.right = insert(node.right, key);
        } else {
            // 键值存在不需要插入
            return node;
        }
        // 不满足 子节点高度差不能大于1
        if (height(node.left) - height(node.right) == 2) {
            if (key.compareTo(node.left.key) < 0) {
                return rotateRight(node);
            } else {
                node.left = rotateLeft(node.left);
                return rotateRight(node);
            }
        } else if (height(node.right) - height(node.left) == 2) {
            if (key.compareTo(node.right.key) > 0) {
                return rotateLeft(node);
            } else {
                node.right = rotateRight(node.right);
                return rotateLeft(node);
            }
        }
        updateHeight(node);
        return node;
    }

    public void insert(T key) {
        root = insert(root, key);
    }


}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值