返回
用Python平衡二叉搜索树
闲谈
2023-12-04 11:47:48
平衡二叉搜索树
平衡二叉搜索树是一种特殊的二叉搜索树,其左右子树的高度差不会超过1。这种特性使得平衡二叉搜索树的查找、插入和删除操作的时间复杂度都为O(log n),其中n是树中的节点数。
实现平衡二叉搜索树的方法
在Python中,实现平衡二叉搜索树有两种常见的方法:AVL树和红黑树。
- AVL树:AVL树是一种高度平衡的二叉搜索树,其左右子树的高度差不会超过1。AVL树的插入和删除操作都可以在O(log n)的时间内完成。
- 红黑树:红黑树也是一种高度平衡的二叉搜索树,其左右子树的高度差不会超过2。红黑树的插入和删除操作都可以在O(log n)的时间内完成。
代码示例
以下是使用AVL树和红黑树实现平衡二叉搜索树的代码示例:
# AVL树
class AVLNode:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
self.height = 1
class AVLTree:
def __init__(self):
self.root = None
def insert(self, key):
new_node = AVLNode(key)
self._insert(new_node)
def _insert(self, new_node):
if self.root is None:
self.root = new_node
else:
self._insert_helper(new_node, self.root)
def _insert_helper(self, new_node, current_node):
if new_node.key < current_node.key:
if current_node.left is None:
current_node.left = new_node
else:
self._insert_helper(new_node, current_node.left)
else:
if current_node.right is None:
current_node.right = new_node
else:
self._insert_helper(new_node, current_node.right)
self._update_height(current_node)
self._balance(current_node)
def _update_height(self, current_node):
current_node.height = 1 + max(self._get_height(current_node.left), self._get_height(current_node.right))
def _get_height(self, node):
if node is None:
return 0
else:
return node.height
def _balance(self, current_node):
balance_factor = self._get_balance_factor(current_node)
# 左子树太高
if balance_factor > 1:
# 左子树的左子树太高
if self._get_balance_factor(current_node.left) < 0:
self._left_rotate(current_node.left)
# 右旋转
self._right_rotate(current_node)
# 右子树太高
elif balance_factor < -1:
# 右子树的右子树太高
if self._get_balance_factor(current_node.right) > 0:
self._right_rotate(current_node.right)
# 左旋转
self._left_rotate(current_node)
def _get_balance_factor(self, node):
if node is None:
return 0
else:
return self._get_height(node.left) - self._get_height(node.right)
def _left_rotate(self, node):
right_child = node.right
node.right = right_child.left
right_child.left = node
self._update_height(node)
self._update_height(right_child)
def _right_rotate(self, node):
left_child = node.left
node.left = left_child.right
left_child.right = node
self._update_height(node)
self._update_height(left_child)
# 红黑树
class RBNode:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
self.color = "red"
class RBTree:
def __init__(self):
self.root = None
def insert(self, key):
new_node = RBNode(key)
self._insert(new_node)
def _insert(self, new_node):
if self.root is None:
self.root = new_node
else:
self._insert_helper(new_node, self.root)
def _insert_helper(self, new_node, current_node):
if new_node.key < current_node.key:
if current_node.left is None:
current_node.left = new_node
else:
self._insert_helper(new_node, current_node.left)
else:
if current_node.right is None:
current_node.right = new_node
else:
self._insert_helper(new_node, current_node.right)
self._fix_insert(new_node)
def _fix_insert(self, new_node):
self._set_color(new_node, "red")
while new_node != self.root and self._get_color(new_node.parent) == "red":
if new_node.parent == new_node.parent.parent.left:
uncle_node = new_node.parent.parent.right
# 叔叔节点是红色
if self._get_color(uncle_node) == "red":
self._set_color(new_node.parent, "black")
self._set_color(uncle_node, "black")
self._set_color(new_node.parent.parent, "red")
new_node = new_node.parent.parent
# 叔叔节点是黑色
else:
if new_node == new_node.parent.right:
new_node = new_node.parent
self._left_rotate(new_node)
self._set_color(new_node.parent, "black")
self._set_color(new_node.parent.parent, "red")
self._right_rotate(new_node.parent.parent)
else:
uncle_node = new_node.parent.parent.left
# 叔叔节点是红色
if self._get_color(uncle_node) == "red":
self._set_color(new_node.parent, "black")
self._set_color(uncle_node, "black")
self._set_color(new_node.parent.parent, "red")
new_node = new_node.parent.parent
# 叔叔节点是黑色
else:
if new_node == new_node.parent.left:
new_node = new_node.parent
self._right_rotate(new_node)
self._set_color(new_node.parent, "black")
self._set_color(new_node.parent.parent, "red")
self._left_rotate(new_node.parent.parent)
self._set_color(self.root, "black")
def _set_color(self, node, color):
if node is not None:
node.color = color
def _get_color(self, node):
if node is None:
return "black"
else:
return node.color
def _left_rotate(self, node):
right_child = node.right
node.right = right_child.left
right_child.left = node
self._set_color(node, "red")
self._set_color(right_child, "black")
def _right_rotate(self, node):
left