返回

AVL 树:平衡二叉搜索树的深度剖析

闲谈

AVL 树:平衡二叉搜索树

在计算机科学中,AVL 树是一种自平衡二叉搜索树,以其发明者 G.M. Adelson-Velsky 和 E.M. Landis 的名字命名。与其他二叉搜索树相比,AVL 树因其高效的搜索和插入操作而受到青睐。

AVL 树的特性

AVL 树通过限制任意节点的两个子树之间的最大高度差来保持平衡,该高度差称为平衡因子。平衡因子始终保持在 -1、0 或 1 之间。

平衡因子的计算

对于一个节点 n,其平衡因子 Bf(n) 定义为其左子树和右子树的高度差:

Bf(n) = height(left_subtree(n)) - height(right_subtree(n))

AVL 树的优势

  • 高效的搜索和插入操作: AVL 树的平衡性质确保搜索和插入操作的时间复杂度为 O(log n),其中 n 是树中的节点数。
  • 动态调整: 当插入或删除节点时,AVL 树会自动调整其结构以保持平衡。
  • 相对简单: 与其他自平衡二叉搜索树(如红黑树)相比,AVL 树的实现相对简单。

与红黑树的对比

AVL 树和红黑树都是自平衡二叉搜索树,但它们的平衡定义不同。AVL 树使用平衡因子,而红黑树使用红黑规则。总的来说,AVL 树的平衡要求更加严格,这导致了更简单的实现。

代码示例

以下 Python 代码演示了如何使用 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):
        new_node = AVLNode(value)
        self.root = self.insert_node(new_node, self.root)

    # 删除节点
    def delete(self, value):
        self.root = self.delete_node(value, self.root)

    # 平衡因子
    def get_balance(self, node):
        if node is None:
            return 0
        return node.left.height - node.right.height

    # 更新高度
    def update_height(self, node):
        if node is None:
            return 0
        node.height = 1 + max(self.update_height(node.left), self.update_height(node.right))

    # 旋转操作
    # LL 旋转
    def left_left_rotation(self, node):
        right_child = node.right
        node.right = right_child.left
        right_child.left = node
        self.update_height(node)
        self.update_height(right_child)
        return right_child

    # RR 旋转
    def right_right_rotation(self, node):
        left_child = node.left
        node.left = left_child.right
        left_child.right = node
        self.update_height(node)
        self.update_height(left_child)
        return left_child

    # LR 旋转
    def left_right_rotation(self, node):
        node.left = self.left_left_rotation(node.left)
        return self.right_right_rotation(node)

    # RL 旋转
    def right_left_rotation(self, node):
        node.right = self.right_right_rotation(node.right)
        return self.left_left_rotation(node)

    # 递归插入节点
    def insert_node(self, new_node, node):
        if node is None:
            return new_node

        if new_node.value < node.value:
            node.left = self.insert_node(new_node, node.left)
        else:
            node.right = self.insert_node(new_node, node.right)

        self.update_height(node)
        balance = self.get_balance(node)

        # LL 旋转
        if balance > 1 and self.get_balance(node.left) >= 0:
            return self.left_left_rotation(node)

        # RR 旋转
        if balance < -1 and self.get_balance(node.right) <= 0:
            return self.right_right_rotation(node)

        # LR 旋转
        if balance > 1 and self.get_balance(node.left) < 0:
            return self.left_right_rotation(node)

        # RL 旋转
        if balance < -1 and self.get_balance(node.right) > 0:
            return self.right_left_rotation(node)

        return node

    # 递归删除节点
    def delete_node(self, value, node):
        if node is None:
            return node

        if value < node.value:
            node.left = self.delete_node(value, node.left)
        elif value > node.value:
            node.right = self.delete_node(value, node.right)
        else:
            if node.left is None:
                temp = node.right
                node = None
                return temp
            elif node.right is None:
                temp = node.left
                node = None
                return temp

            temp = self.get_predecessor(node.left)
            node.value = temp.value
            node.left = self.delete_node(temp.value, node.left)

        if node is None:
            return node

        self.update_height(node)
        balance = self.get_balance(node)

        # LL 旋转
        if balance > 1 and self.get_balance(node.left) >= 0:
            return self.left_left_rotation(node)

        # RR 旋转
        if balance < -1 and self.get_balance(node.right) <= 0:
            return self.right_right_rotation(node)

        # LR 旋转
        if balance > 1 and self.get_balance(node.left) < 0:
            return self.left_right_rotation(node)

        # RL 旋转
        if balance < -1 and self.get_balance(node.right) > 0:
            return self.right_left_rotation(node)

        return node

    # 获取前驱节点
    def get_predecessor(self, node):
        if node.right is None:
            return node
        return self.get_predecessor(node.right)

# 使用 AVL 树
avl_tree = AVLTree()
avl_tree.insert(10)
avl_tree.insert(5)
avl_tree.insert(15)
avl_tree.insert(3)
avl_tree.insert(7)
avl_tree.insert(12)
avl_tree.insert(20)

# 搜索节点
node = avl_tree.search(12)
if node:
    print("Node found:", node.value)
else:
    print("Node not found")

# 删除节点
avl_tree.delete(7)

结论

AVL 树是一种高效且通用的自平衡二叉搜索树,它广泛应用于各种场景中,包括数据库、搜索引擎和内存管理。其平衡特性确保了高效的搜索和插入操作,使其成为处理大量数据的理想选择。