红黑树简介
红黑树是一种自平衡的二叉查找树,它通过在树中添加颜色属性来维护树的平衡。红黑树中的节点可以是红色或黑色,并遵循以下规则:
- 每个节点要么是红色,要么是黑色。
- 根节点是黑色。
- 所有叶子(NIL节点)都是黑色。
- 如果一个节点是红色的,则它的两个子节点都是黑色的。
- 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。
在线测试题解析
测试题1:红黑树的插入操作
题目描述:在红黑树中插入一个红色节点,解析插入操作的过程。
解析:
- 插入节点:首先,将新节点插入到红黑树中,保持二叉查找树的性质。
- 红色节点:将新节点设为红色。
- 检查规则:检查插入操作后是否违反了红黑树的规则。
- 调整树:如果违反了规则,通过旋转和重新着色来调整树,使其重新满足红黑树的性质。
案例:
class Node:
def __init__(self, data, color="red"):
self.data = data
self.color = color
self.left = None
self.right = None
self.parent = None
class RedBlackTree:
def __init__(self):
self.NIL = Node(data=None, color="black")
self.root = self.NIL
def insert(self, data):
new_node = Node(data)
new_node.left = self.NIL
new_node.right = self.NIL
parent = None
current = self.root
while current != self.NIL:
parent = current
if new_node.data < current.data:
current = current.left
else:
current = current.right
new_node.parent = parent
if parent is None:
self.root = new_node
elif new_node.data < parent.data:
parent.left = new_node
else:
parent.right = new_node
new_node.color = "red"
self.fix_insert(new_node)
def fix_insert(self, node):
while node != self.root and node.parent.color == "red":
if node.parent == node.parent.parent.left:
uncle = node.parent.parent.right
if uncle.color == "red":
node.parent.color = "black"
uncle.color = "black"
node.parent.parent.color = "red"
node = node.parent.parent
else:
if node == node.parent.right:
node = node.parent
self.left_rotate(node)
node.parent.color = "black"
node.parent.parent.color = "red"
self.right_rotate(node.parent.parent)
else:
uncle = node.parent.parent.left
if uncle.color == "red":
node.parent.color = "black"
uncle.color = "black"
node.parent.parent.color = "red"
node = node.parent.parent
else:
if node == node.parent.left:
node = node.parent
self.right_rotate(node)
node.parent.color = "black"
node.parent.parent.color = "red"
self.left_rotate(node.parent.parent)
self.root.color = "black"
def left_rotate(self, x):
y = x.right
x.right = y.left
if y.left != self.NIL:
y.left.parent = x
y.parent = x.parent
if x.parent is None:
self.root = y
elif x == x.parent.left:
x.parent.left = y
else:
x.parent.right = y
y.left = x
x.parent = y
def right_rotate(self, y):
x = y.left
y.left = x.right
if x.right != self.NIL:
x.right.parent = y
x.parent = y.parent
if y.parent is None:
self.root = x
elif y == y.parent.right:
y.parent.right = x
else:
y.parent.left = x
x.right = y
y.parent = x
rbt = RedBlackTree()
rbt.insert(10)
rbt.insert(18)
rbt.insert(7)
rbt.insert(15)
rbt.insert(16)
rbt.insert(30)
rbt.insert(25)
rbt.insert(40)
rbt.insert(60)
rbt.insert(2)
rbt.insert(1)
rbt.insert(70)
测试题2:红黑树的删除操作
题目描述:在红黑树中删除一个节点,解析删除操作的过程。
解析:
- 删除节点:首先,删除节点,保持二叉查找树的性质。
- 处理叶子节点:如果删除的是叶子节点,则不需要进行特殊处理。
- 处理红色节点:如果删除的是红色节点,则不需要进行特殊处理。
- 处理黑色节点:如果删除的是黑色节点,则需要通过旋转和重新着色来调整树,使其重新满足红黑树的性质。
案例:
def delete(self, data):
node_to_delete = self.search(data)
if node_to_delete is not None:
self.delete_node(node_to_delete)
def delete_node(self, node):
if node.left == self.NIL and node.right == self.NIL:
if node == self.root:
self.root = self.NIL
elif node == node.parent.left:
node.parent.left = self.NIL
else:
node.parent.right = self.NIL
return
if node.left == self.NIL:
if node == self.root:
self.root = node.right
elif node == node.parent.left:
node.parent.left = node.right
else:
node.parent.right = node.right
node.right.parent = node.parent
elif node.right == self.NIL:
if node == self.root:
self.root = node.left
elif node == node.parent.left:
node.parent.left = node.left
else:
node.parent.right = node.left
node.left.parent = node.parent
else:
successor = self.get_successor(node)
if successor != node.right:
successor.left = node.left
successor.left.parent = successor
else:
successor.right = node.right
successor.right.parent = successor
if node == self.root:
self.root = successor
elif node == node.parent.left:
node.parent.left = successor
else:
node.parent.right = successor
successor.parent = node.parent
if node.color == "black":
self.fix_delete(successor)
def fix_delete(self, node):
while node != self.root and node.color == "black":
if node == node.parent.left:
sibling = node.parent.right
if sibling.color == "red":
sibling.color = "black"
node.parent.color = "red"
self.left_rotate(node.parent)
sibling = node.parent.right
if sibling.left.color == "black" and sibling.right.color == "black":
sibling.color = "red"
node = node.parent
else:
if sibling.right.color == "black":
sibling.left.color = "black"
sibling.color = "red"
self.right_rotate(sibling)
sibling = node.parent.right
sibling.color = node.parent.color
node.parent.color = "black"
sibling.right.color = "black"
self.left_rotate(node.parent)
node = self.root
else:
sibling = node.parent.left
if sibling.color == "red":
sibling.color = "black"
node.parent.color = "red"
self.right_rotate(node.parent)
sibling = node.parent.left
if sibling.right.color == "black" and sibling.left.color == "black":
sibling.color = "red"
node = node.parent
else:
if sibling.left.color == "black":
sibling.right.color = "black"
sibling.color = "red"
self.left_rotate(sibling)
sibling = node.parent.left
sibling.color = node.parent.color
node.parent.color = "black"
sibling.left.color = "black"
self.right_rotate(node.parent)
node = self.root
node.color = "black"
测试题3:红黑树的查找操作
题目描述:在红黑树中查找一个节点,解析查找操作的过程。
解析:
- 查找节点:从根节点开始,递归地在左子树或右子树中查找目标节点。
- 返回结果:如果找到目标节点,则返回该节点;否则,返回None。
案例:
def search(self, data):
return self._search(self.root, data)
def _search(self, node, data):
if node == self.NIL or data == node.data:
return node
if data < node.data:
return self._search(node.left, data)
return self._search(node.right, data)
总结
通过以上解析和案例,相信你已经对红黑树有了更深入的了解。在实际应用中,红黑树常用于实现各种数据结构,如字典、集合和优先队列等。希望这些解析和案例能帮助你更好地掌握红黑树。
