返回

AVL树轻松搞定:旋转平衡的艺术

后端

AVL树:旋转平衡的艺术

初识AVL树

AVL树是一种自平衡二叉查找树,由两位苏联数学家Adelson-Velsky和Landis于1962年提出。与普通二叉查找树不同,AVL树始终保持左右子树的高度平衡,确保高效查找和修改。

AVL树的特性

AVL树具有以下特性:

  • 是一棵二叉查找树
  • 左右子树的高度差绝对值不超过1
  • 通过旋转操作维持平衡

AVL树操作

AVL树的基本操作包括插入、删除、查找和旋转。

插入

  1. 按照二叉查找树规则插入元素
  2. 计算每一层平衡因子
  3. 若平衡因子绝对值大于1,进行旋转

删除

  1. 按照二叉查找树规则删除元素
  2. 计算每一层平衡因子
  3. 若平衡因子绝对值大于1,进行旋转

查找

AVL树是一棵平衡树,查找效率很高,按照二叉查找树规则进行查找。

旋转

AVL树中的旋转操作分为四种:

  • 左旋:将右子树的左子树提升为右子树,并将右子树提升为根节点
  • 右旋:将左子树的右子树提升为左子树,并将左子树提升为根节点
  • 左双旋:先对右子树左旋,再对自身右旋
  • 右双旋:先对左子树右旋,再对自身左旋

AVL树的优势

  • 高效查找:AVL树是一棵平衡树,查找时间复杂度为O(log n)
  • 高效修改:AVL树通过旋转操作保持平衡,修改时间复杂度也为O(log n)
  • 简单实现:AVL树的算法相对简单,易于理解和实现

代码示例:

class AVLNode:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None
        self.height = 1

class AVLTree:
    def __init__(self):
        self.root = None

    def insert(self, value):
        # Insert node like a normal BST
        new_node = AVLNode(value)
        self.root = self._insert(new_node, self.root)

    def _insert(self, new_node, node):
        # If tree is empty, return new node
        if node is None:
            return new_node

        # Insert node like a normal BST
        if new_node.value < node.value:
            node.left = self._insert(new_node, node.left)
        else:
            node.right = self._insert(new_node, node.right)

        # Update height of parent node
        node.height = 1 + max(self._height(node.left), self._height(node.right))

        # Check balance factor
        balance_factor = self._balance_factor(node)
        
        # Perform rotations if necessary
        if balance_factor > 1:
            if self._balance_factor(node.left) < 0:
                node.left = self._left_rotate(node.left)
            node = self._right_rotate(node)
        elif balance_factor < -1:
            if self._balance_factor(node.right) > 0:
                node.right = self._right_rotate(node.right)
            node = self._left_rotate(node)

        return node

    def _height(self, node):
        if node is None:
            return 0
        return node.height

    def _balance_factor(self, node):
        if node is None:
            return 0
        return self._height(node.left) - self._height(node.right)

    def _left_rotate(self, node):
        right_child = node.right
        node.right = right_child.left
        right_child.left = node
        
        # Update heights
        node.height = 1 + max(self._height(node.left), self._height(node.right))
        right_child.height = 1 + max(self._height(right_child.left), self._height(right_child.right))
        
        return right_child

    def _right_rotate(self, node):
        left_child = node.left
        node.left = left_child.right
        left_child.right = node
        
        # Update heights
        node.height = 1 + max(self._height(node.left), self._height(node.right))
        left_child.height = 1 + max(self._height(left_child.left), self._height(left_child.right))
        
        return left_child

常见问题解答

Q1:AVL树和普通二叉查找树有什么区别?
A1:AVL树是一棵自平衡二叉查找树,始终保持左右子树高度平衡,而普通二叉查找树没有这样的特性。

Q2:AVL树的插入和删除操作如何保持平衡?
A2:AVL树通过旋转操作来保持平衡,当插入或删除一个元素后,计算每一层的平衡因子,如果平衡因子绝对值大于1,就进行旋转操作。

Q3:AVL树的查找时间复杂度是多少?
A3:AVL树是一棵平衡树,查找时间复杂度为O(log n)。

Q4:AVL树的修改时间复杂度是多少?
A4:AVL树通过旋转操作保持平衡,修改时间复杂度也为O(log n)。

Q5:AVL树有什么优势?
A5:AVL树具有查找和修改效率高、简单易于实现的优势。