返回
AVL树轻松搞定:旋转平衡的艺术
后端
2023-06-27 23:42:21
AVL树:旋转平衡的艺术
初识AVL树
AVL树是一种自平衡二叉查找树,由两位苏联数学家Adelson-Velsky和Landis于1962年提出。与普通二叉查找树不同,AVL树始终保持左右子树的高度平衡,确保高效查找和修改。
AVL树的特性
AVL树具有以下特性:
- 是一棵二叉查找树
- 左右子树的高度差绝对值不超过1
- 通过旋转操作维持平衡
AVL树操作
AVL树的基本操作包括插入、删除、查找和旋转。
插入
- 按照二叉查找树规则插入元素
- 计算每一层平衡因子
- 若平衡因子绝对值大于1,进行旋转
删除
- 按照二叉查找树规则删除元素
- 计算每一层平衡因子
- 若平衡因子绝对值大于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树具有查找和修改效率高、简单易于实现的优势。