欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 高考 > 二叉树算法之平衡二叉树(AVL Tree)详细解读

二叉树算法之平衡二叉树(AVL Tree)详细解读

2025/4/29 10:36:38 来源:https://blog.csdn.net/m0_61840987/article/details/143051262  浏览:    关键词:二叉树算法之平衡二叉树(AVL Tree)详细解读

平衡二叉树(AVL Tree)是一种自平衡的二叉搜索树(Binary Search Tree, BST),其特点是通过维护树的高度平衡来保证基本操作(插入、删除和查找)的时间复杂度为 O(log⁡n)。AVL树是由G.M. Adelson-Velsky和E.M. Landis于1962年提出的,因此得名“AVL树”。

1. AVL树的定义

AVL树的每个节点都有一个平衡因子(Balance Factor),其值为该节点的左子树高度减去右子树高度。对于任何一个节点,平衡因子的值只能为 −1、0 或 1,表示树的高度是平衡的。如果一个节点的平衡因子为 −1,表示右子树比左子树高;如果平衡因子为 1,表示左子树比右子树高;如果平衡因子为 0,表示左右子树高度相等。

2. AVL树的特性

  • 性质:对于每个节点,左子树和右子树的高度差(平衡因子)最多为1。
  • 高度平衡:由于AVL树保持高度平衡,查找、插入和删除的时间复杂度都是 O(log⁡n)
  • 自平衡:在插入或删除节点后,AVL树会通过旋转操作来恢复平衡。

3. AVL树的旋转

当AVL树失去平衡时,通过旋转操作来恢复平衡。主要的旋转操作有四种:

  1. 右旋(Right Rotation)

    • 当某个节点的左子树比右子树高时,进行右旋转,以恢复平衡。
    • 适用于插入在左子树的左侧(LL型)。
  2. 左旋(Left Rotation)

    • 当某个节点的右子树比左子树高时,进行左旋转,以恢复平衡。
    • 适用于插入在右子树的右侧(RR型)。
  3. 左-右旋(Left-Right Rotation)

    • 当某个节点的左子树比右子树高,且插入在左子树的右侧时,先进行左旋再进行右旋,以恢复平衡(LR型)。
  4. 右-左旋(Right-Left Rotation)

    • 当某个节点的右子树比左子树高,且插入在右子树的左侧时,先进行右旋再进行左旋,以恢复平衡(RL型)。

4. AVL树的插入操作

插入操作分为以下步骤:

  1. 普通的二叉搜索树插入:按照二叉搜索树的性质插入新节点。
  2. 更新平衡因子:从插入位置向上更新每个节点的高度和平衡因子。
  3. 检查平衡:如果某个节点的平衡因子变为 −2 或 2,则需要进行旋转操作。
  4. 旋转恢复平衡:根据失衡的情况,选择适当的旋转操作来恢复平衡。

AVL树的Java实现

以下是AVL树的Java实现示例,包括插入和旋转操作:

class AVLTreeNode {int key;int height;AVLTreeNode left, right;public AVLTreeNode(int key) {this.key = key;this.height = 1;}
}class AVLTree {private AVLTreeNode root;// 获取节点高度private int height(AVLTreeNode node) {return node == null ? 0 : node.height;}// 获取平衡因子private int getBalance(AVLTreeNode node) {return node == null ? 0 : height(node.left) - height(node.right);}// 右旋private AVLTreeNode rightRotate(AVLTreeNode y) {AVLTreeNode x = y.left;AVLTreeNode T2 = x.right;// 进行旋转x.right = y;y.left = T2;// 更新高度y.height = Math.max(height(y.left), height(y.right)) + 1;x.height = Math.max(height(x.left), height(x.right)) + 1;return x; // 新的根节点}// 左旋private AVLTreeNode leftRotate(AVLTreeNode x) {AVLTreeNode y = x.right;AVLTreeNode T2 = y.left;// 进行旋转y.left = x;x.right = T2;// 更新高度x.height = Math.max(height(x.left), height(x.right)) + 1;y.height = Math.max(height(y.left), height(y.right)) + 1;return y; // 新的根节点}// 插入节点public AVLTreeNode insert(AVLTreeNode node, int key) {// 1. 执行普通的BST插入if (node == null) {return new AVLTreeNode(key);}if (key < node.key) {node.left = insert(node.left, key);} else if (key > node.key) {node.right = insert(node.right, key);} else { // 不允许重复值return node;}// 2. 更新当前节点的高度node.height = Math.max(height(node.left), height(node.right)) + 1;// 3. 获取平衡因子int balance = getBalance(node);// 4. 如果节点失衡,则进行旋转操作// LL型if (balance > 1 && key < node.left.key) {return rightRotate(node);}// RR型if (balance < -1 && key > node.right.key) {return leftRotate(node);}// LR型if (balance > 1 && key > node.left.key) {node.left = leftRotate(node.left);return rightRotate(node);}// RL型if (balance < -1 && key < node.right.key) {node.right = rightRotate(node.right);return leftRotate(node);}return node; // 返回未变化的节点指针}// 中序遍历public void inorder(AVLTreeNode node) {if (node != null) {inorder(node.left);System.out.print(node.key + " ");inorder(node.right);}}public void display() {inorder(root);System.out.println();}public void insert(int key) {root = insert(root, key);}public static void main(String[] args) {AVLTree avlTree = new AVLTree();int[] keys = {10, 20, 30, 40, 50, 25};for (int key : keys) {avlTree.insert(key);}System.out.println("中序遍历 AVL 树:");avlTree.display(); // 输出: 10 20 25 30 40 50}
}

代码解读

  1. AVLTreeNode类:定义AVL树的节点,包含键值、节点高度和左右子节点指针。

  2. AVLTree类:包含根节点和插入、旋转、获取高度及平衡因子的相关方法。

  3. 插入操作

    • 在插入方法中,先执行标准的二叉搜索树插入。
    • 更新节点的高度,并计算平衡因子。
    • 根据平衡因子的值判断是否需要旋转,以恢复平衡。
  4. 旋转操作

    • 右旋和左旋方法用于在AVL树失衡时,进行旋转操作以恢复平衡。
  5. 中序遍历

    • 中序遍历方法用于展示AVL树的节点,确保输出的顺序是升序的。

5. AVL树的优缺点

优点
  • 自平衡:保持高度平衡,保证 O(log⁡n) 的时间复杂度。
  • 高效查找:由于是二叉搜索树,查找操作高效。
缺点
  • 插入和删除复杂:相较于普通二叉搜索树,AVL树的插入和删除操作复杂,需要进行旋转。
  • 空间复杂度:相对其他树结构(如红黑树),AVL树的空间复杂度可能更高,因为需要存储每个节点的高度信息。

6. 应用场景

  • AVL树常用于需要频繁进行插入和删除操作的场景,如数据库索引、内存管理等。
  • 由于其高度平衡的特性,适合对查询性能有严格要求的应用。

AVL树是一种强大的数据结构,能够在高效查找的同时,保持树的结构平衡,是许多应用中的重要组成部分。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词