📜  数据结构和算法-AVL树(1)

📅  最后修改于: 2023-12-03 15:26:09.671000             🧑  作者: Mango

数据结构和算法 - AVL树

什么是AVL树

AVL树是一种平衡二叉搜索树,它的每一个节点的左右子树的高度相差不超过1。

AVL树的特性

AVL树的特性如下:

  • 左子树和右子树的高度最多相差1,这就保证了插入、删除、查询的最坏时间为O(logn);
  • 对于每个节点,它的左子树和右子树的高度差不能大于1,在插入、删除节点的时候,需要通过旋转来维持它的平衡性;
  • AVL树是自平衡的,也就意味着AVL树的高度近似logn,所以在插入、删除、查询等操作时效率很高。
AVL树的平衡操作

AVL树的平衡操作包括左旋和右旋。

  • 左旋是指以根节点为基础,将根节点的右子树作为新的子树,并将原右子树的左子树作为新的右子树;
  • 右旋与左旋是相反的,它是将根节点的左子树作为新的子树,并将原左子树的右子树作为新的左子树。

AVL树的平衡操作代码示例:

def left_rotate(node):
    r = node.right
    node.right = r.left
    r.left = node
    node.height = max(get_height(node.left), get_height(node.right)) + 1
    r.height = max(get_height(r.left), get_height(r.right)) + 1
    return r

def right_rotate(node):
    l = node.left
    node.left = l.right
    l.right = node
    node.height = max(get_height(node.left), get_height(node.right)) + 1
    l.height = max(get_height(l.left), get_height(l.right)) + 1
    return l
AVL树的插入操作

AVL树的插入操作需要先进行二叉搜索树的插入操作,然后再对每个节点的平衡因子进行判断,若平衡因子不是-1、0、1,则需要进行旋转操作。

AVL树的插入操作代码示例:

def insert(root, key):
    if not root:
        return Node(key)
    elif key < root.key:
        root.left = insert(root.left, key)
    else:
        root.right = insert(root.right, key)
    root.height = max(get_height(root.left), get_height(root.right)) + 1
    balance = get_balance(root)
    if balance > 1 and key < root.left.key:
        return right_rotate(root)
    if balance < -1 and key > root.right.key:
        return left_rotate(root)
    if balance > 1 and key > root.left.key:
        root.left = left_rotate(root.left)
        return right_rotate(root)
    if balance < -1 and key < root.right.key:
        root.right = right_rotate(root.right)
        return left_rotate(root)
    return root
AVL树的删除操作

AVL树的删除操作同样需要进行二叉搜索树的删除操作,然后再对每个节点的平衡因子进行检查和修复。

AVL树的删除操作代码示例:

def delete(root, key):
    if not root:
        return root
    elif key < root.key:
        root.left = delete(root.left, key)
    elif key > root.key:
        root.right = delete(root.right, key)
    else:
        if not root.left and not root.right:
            root = None
        elif not root.left:
            root = root.right
        elif not root.right:
            root = root.left
        else:
            temp = get_min_node(root.right)
            root.key = temp.key
            root.right = delete(root.right, temp.key)
    if not root:
        return root
    root.height = max(get_height(root.left), get_height(root.right)) + 1
    balance = get_balance(root)
    if balance > 1 and get_balance(root.left) >= 0:
        return right_rotate(root)
    if balance < -1 and get_balance(root.right) <= 0:
        return left_rotate(root)
    if balance > 1 and get_balance(root.left) < 0:
        root.left = left_rotate(root.left)
        return right_rotate(root)
    if balance < -1 and get_balance(root.right) > 0:
        root.right = right_rotate(root.right)
        return left_rotate(root)
    return root
总结

AVL树是一种自平衡的二叉搜索树,它的每个节点的左右子树的高度相差不超过1。插入、删除、查询等操作的时间复杂度为O(logn),并且AVL树的高度近似logn,操作效率很高。