You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编程新手求助:平衡二叉搜索树插入与删除方法实现

平衡二叉搜索树(AVL树)插入与删除实现方案

首先你需要完善Node类的定义,AVL树的节点需要存储高度信息来判断平衡状态:

class Node {
    int key;
    int height;
    Node left, right;

    Node(int key) {
        this.key = key;
        this.height = 1; // 新节点初始高度为1
        this.left = this.right = null;
    }
}

插入方法实现

AVL树的插入分两步:先执行普通二叉搜索树的插入逻辑,再回溯调整树的平衡,通过旋转修正失衡节点。

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

// 递归插入节点并维护AVL平衡
private Node insertRecursive(Node node, int key) {
    // 1. 执行普通BST插入
    if (node == null) {
        return new Node(key);
    }

    if (key < node.key) {
        node.left = insertRecursive(node.left, key);
    } else if (key > node.key) {
        node.right = insertRecursive(node.right, key);
    } else {
        // BST不允许重复键,直接返回原节点
        return node;
    }

    // 2. 更新当前节点的高度
    node.height = 1 + Math.max(getHeight(node.left), getHeight(node.right));

    // 3. 计算平衡因子,判断是否失衡
    int balanceFactor = getBalanceFactor(node);

    // 4. 处理四种失衡情况
    // 情况1:LL型,右旋
    if (balanceFactor > 1 && key < node.left.key) {
        return rightRotate(node);
    }

    // 情况2:RR型,左旋
    if (balanceFactor < -1 && key > node.right.key) {
        return leftRotate(node);
    }

    // 情况3:LR型,先左旋左子节点,再右旋当前节点
    if (balanceFactor > 1 && key > node.left.key) {
        node.left = leftRotate(node.left);
        return rightRotate(node);
    }

    // 情况4:RL型,先右旋右子节点,再左旋当前节点
    if (balanceFactor < -1 && key < node.right.key) {
        node.right = rightRotate(node.right);
        return leftRotate(node);
    }

    // 未失衡,返回原节点
    return node;
}

// 获取节点高度
private int getHeight(Node node) {
    return node == null ? 0 : node.height;
}

// 计算平衡因子(左子树高度 - 右子树高度)
private int getBalanceFactor(Node node) {
    return node == null ? 0 : getHeight(node.left) - getHeight(node.right);
}

// 右旋操作
private Node rightRotate(Node y) {
    Node x = y.left;
    Node T2 = x.right;

    // 执行右旋
    x.right = y;
    y.left = T2;

    // 更新高度
    y.height = 1 + Math.max(getHeight(y.left), getHeight(y.right));
    x.height = 1 + Math.max(getHeight(x.left), getHeight(x.right));

    // 返回新的根节点
    return x;
}

// 左旋操作
private Node leftRotate(Node x) {
    Node y = x.right;
    Node T2 = y.left;

    // 执行左旋
    y.left = x;
    x.right = T2;

    // 更新高度
    x.height = 1 + Math.max(getHeight(x.left), getHeight(x.right));
    y.height = 1 + Math.max(getHeight(y.left), getHeight(y.right));

    // 返回新的根节点
    return y;
}

删除方法实现

AVL树的删除同样先执行普通BST的删除逻辑,再回溯调整平衡(删除后可能出现多层失衡,需要逐层修正)。

public void delete(int key) {
    root = deleteRecursive(root, key);
}

// 递归删除节点并维护AVL平衡
private Node deleteRecursive(Node node, int key) {
    // 1. 执行普通BST删除
    if (node == null) {
        return node; // 未找到要删除的节点
    }

    if (key < node.key) {
        node.left = deleteRecursive(node.left, key);
    } else if (key > node.key) {
        node.right = deleteRecursive(node.right, key);
    } else {
        // 找到要删除的节点,处理三种情况
        // 情况1:只有右子树或无子树
        if (node.left == null) {
            return node.right;
        }
        // 情况2:只有左子树
        else if (node.right == null) {
            return node.left;
        }
        // 情况3:有两个子树,找右子树的最小节点替代
        Node temp = getMinValueNode(node.right);
        node.key = temp.key;
        // 删除右子树的最小节点
        node.right = deleteRecursive(node.right, temp.key);
    }

    // 如果删除后树为空,直接返回
    if (node == null) {
        return node;
    }

    // 2. 更新当前节点的高度
    node.height = 1 + Math.max(getHeight(node.left), getHeight(node.right));

    // 3. 计算平衡因子,判断是否失衡
    int balanceFactor = getBalanceFactor(node);

    // 4. 处理四种失衡情况
    // 情况1:LL型,右旋
    if (balanceFactor > 1 && getBalanceFactor(node.left) >= 0) {
        return rightRotate(node);
    }

    // 情况2:LR型,先左旋左子节点,再右旋当前节点
    if (balanceFactor > 1 && getBalanceFactor(node.left) < 0) {
        node.left = leftRotate(node.left);
        return rightRotate(node);
    }

    // 情况3:RR型,左旋
    if (balanceFactor < -1 && getBalanceFactor(node.right) <= 0) {
        return leftRotate(node);
    }

    // 情况4:RL型,先右旋右子节点,再左旋当前节点
    if (balanceFactor < -1 && getBalanceFactor(node.right) > 0) {
        node.right = rightRotate(node.right);
        return leftRotate(node);
    }

    // 未失衡,返回原节点
    return node;
}

// 获取树中的最小节点(用于BST删除的替代节点)
private Node getMinValueNode(Node node) {
    Node current = node;
    // 一直向左找,直到左子节点为空
    while (current.left != null) {
        current = current.left;
    }
    return current;
}

关键说明

  • 高度维护:每次插入/删除后必须更新节点高度,这是计算平衡因子的基础。
  • 平衡因子:平衡因子绝对值超过1时,说明节点失衡,需要通过旋转修正。
  • 旋转操作:四种旋转是AVL树保持平衡的核心,要对应每种旋转的失衡场景理解。

内容的提问来源于stack exchange,提问作者Gareth Simpson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 11:55:18