Java中的AVL树

Java中的AVL树

AVL树是一种自平衡二叉查找树,意味着任何时候任何操作后,它都会自动调整自己的结构以保持平衡状态。它的名字来源于其发明者G.M.Adelson-Velsky和E.M.Landis。

在AVL树中,任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下的时间复杂度都是O(log n)。增加和删除元素的操作则可能需要借由一次到多次树旋转,以实现树的重新平衡。

AVL树的定义

AVL树的节点定义如下:

static class avlNode {
    int key;
    Object value;
    avlNode left;
    avlNode right;
    int height;

    public avlNode(int key) {
        this.key = key;
    }

    public avlNode(int key, Object value) {
        this.key = key;
        this.value = value;
    }

    public avlNode(int key, Object value, avlNode left, avlNode right) {
        this.key = key;
        this.value = value;
        this.left = left;
        this.right = right;
    }
}

每个节点包含一个键、一个值、一个左子节点、一个右子节点以及一个表示节点高度的字段。

AVL树的旋转操作

AVL树通过四种旋转操作来保持平衡:左旋、右旋、左右旋和右左旋。

  • 左旋(Left Rotate)
private avlNode leftRotate(avlNode node) {
    avlNode rightChild = node.right;
    node.left = rightChild.left;
    rightChild.left = node;
    node.height = getHeight(node);
    rightChild.height = getHeight(rightChild);
    return rightChild;
}
  • 右旋(Right Rotate)
private avlNode rightRotate(avlNode node) {
    avlNode leftChild = node.left;
    node.left = leftChild.right;
    leftChild.right = node;
    node.height = getHeight(node);
    leftChild.height = getHeight(leftChild);
    return leftChild;
}
  • 左右旋(Left Right Rotate)
private avlNode LRRotate(avlNode node) {
    node.left = leftRotate(node.left);
    return rightRotate(node);
}
  • 右左旋(Right Left Rotate)
private avlNode RLRotate(avlNode node) {
    node.right = rightRotate(node.right);
    return leftRotate(node);
}

AVL树的插入和删除操作

AVL树的插入和删除操作需要在操作后检查并保持树的平衡。

  • 插入操作
public void put(int key, Object value) {
    root = doPut(root, key, value);
}

private avlNode doPut(avlNode node, int key, Object value) {
    if (node == null) {
        avlNode avlNode = new avlNode(key, value);
        return avlNode;
    }
    if (node.key > key)
        node.left = doPut(node.left, key, value);
    else if (node.key < key)
        node.right = doPut(node.right, key, value);
    else
        node.value = value;
    return balance(node);
}
  • 删除操作
public void remove(int key) {
    root = doRemove(root, key);
}

private avlNode doRemove(avlNode node, int key) {
    if (node == null) {
        return node;
    }
    if (node.key > key) {
        node.left = doRemove(node.left, key);
    } else if (node.key < key) {
        node.right = doRemove(node.right, key);
    } else {
        if (node.right == null) {
            return node.left;
        } else if (node.left == null) {
            return node.right;
        } else {
            avlNode p = node.right;
            while (p.left != null) {
                p = p.left;
            }
            p.right = doRemove(node.right,p.key);
            p.left = node.left;
            node = p;
        }
    }
    node.height = getHeight(node);
    return balance(node);
}
  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
AVL树是一种自平衡的二叉搜索树,它的升序遍历可以通过序遍历来实现。下面是Java实现AVL树升序遍历的示例代码: ```java // AVL树节点定义 class Node { int key; int height; Node left; Node right; Node(int key) { this.key = key; this.height = 1; } } // AVL树类定义 class AVLTree { Node root; // 获取节点的高度 int getHeight(Node node) { if (node == null) { return 0; } return node.height; } // 更新节点的高度 void updateHeight(Node node) { node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1; } // 获取节点的平衡因子 int getBalanceFactor(Node node) { if (node == null) { return 0; } return getHeight(node.left) - getHeight(node.right); } // 右旋操作 Node rotateRight(Node y) { Node x = y.left; Node T2 = x.right; x.right = y; y.left = T2; updateHeight(y); updateHeight(x); return x; } // 左旋操作 Node rotateLeft(Node x) { Node y = x.right; Node T2 = y.left; y.left = x; x.right = T2; updateHeight(x); updateHeight(y); return y; } // 插入节点 Node insertNode(Node node, int key) { if (node == null) { return new Node(key); } if (key < node.key) { node.left = insertNode(node.left, key); } else if (key > node.key) { node.right = insertNode(node.right, key); } else { return node; // 不允许插入重复的节点 } updateHeight(node); int balanceFactor = getBalanceFactor(node); // 左旋操作 if (balanceFactor > 1 && key < node.left.key) { return rotateRight(node); } // 右旋操作 if (balanceFactor < -1 && key > node.right.key) { return rotateLeft(node); } // 左右旋操作 if (balanceFactor > 1 && key > node.left.key) { node.left = rotateLeft(node.left); return rotateRight(node); } // 右左旋操作 if (balanceFactor < -1 && key < node.right.key) { node.right = rotateRight(node.right); return rotateLeft(node); } return node; } // 序遍历 void inorderTraversal(Node node) { if (node != null) { inorderTraversal(node.left); System.out.print(node.key + " "); inorderTraversal(node.right); } } } // 测试代码 public class Main { public static void main(String[] args) { AVLTree tree = new AVLTree(); tree.root = tree.insertNode(tree.root, 10); tree.root = tree.insertNode(tree.root, 20); tree.root = tree.insertNode(tree.root, 30); tree.root = tree.insertNode(tree.root, 40); tree.root = tree.insertNode(tree.root, 50); tree.root = tree.insertNode(tree.root, 25); System.out.println("AVL树的升序遍历结果:"); tree.inorderTraversal(tree.root); } } ``` 运行以上代码,输出结果为:10 20 25 30 40 50,即AVL树的升序遍历结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林小果呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值