数据结构编程实践:Python版系列第8讲——红黑树
红黑树是一种自平衡的二叉搜索树,它确保树的路径从根到叶子的最长的一条不会超过最短的一条的两倍,通过添加颜色属性来约束树的平衡性。下面是红黑树的一些基本性质和Python实现示例,以帮助你理解红黑树的工作方式。
红黑树性质
- 每个节点是红色或黑色。
- 根节点是黑色。
- 每个叶子节点(NIL节点,空节点)是黑色。
- 如果一个节点是红色,则它的两个子节点都是黑色。
- 从任何节点到其每个叶子的所有路径都包含相同数量的黑色节点。
这些性质保证了红黑树的平衡性,从而实现O(log n)的时间复杂度来执行查找、插入和删除操作。
Python实现概述
以下是红黑树的简单实现示例,包含插入和基础结构代码。为了简化演示,叶子节点初始化有助于理解树的结构:
class Node:
def __init__(self, data, color='red', parent=None, left=None, right=None):
self.data = data
self.color = color
self.parent = parent
self.left = left
self.right = right
class RedBlackTree:
def __init__(self):
self.NIL_LEAF = Node(data=None, color='black') # Sentinel node to represent nil
self.root = self.NIL_LEAF
def rotate_left(self, node):
right_child = node.right
node.right = right_child.left
if right_child.left != self.NIL_LEAF:
right_child.left.parent = node
right_child.parent = node.parent
if node.parent is None:
self.root = right_child
elif node == node.parent.left:
node.parent.left = right_child
else:
node.parent.right = right_child
right_child.left = node
node.parent = right_child
def rotate_right(self, node):
left_child = node.left
node.left = left_child.right
if left_child.right != self.NIL_LEAF:
left_child.right.parent = node
left_child.parent = node.parent
if node.parent is None:
self.root = left_child
elif node == node.parent.right:
node.parent.right = left_child
else:
node.parent.left = left_child
left_child.right = node
node.parent = left_child
def insert(self, data):
new_node = Node(data)
new_node.left = self.NIL_LEAF
new_node.right = self.NIL_LEAF
parent = None
current = self.root
while current != self.NIL_LEAF:
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
self.root.color = 'black'
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.rotate_left(node)
node.parent.color = 'black'
node.parent.parent.color = 'red'
self.rotate_right(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.rotate_right(node)
node.parent.color = 'black'
node.parent.parent.color = 'red'
self.rotate_left(node.parent.parent)
self.root.color = 'black'
# 示例用法
rbt = RedBlackTree()
rbt.insert(10)
rbt.insert(18)
rbt.insert(7)
rbt.insert(15)
rbt.insert(16)
说明
- 旋转操作:在插入过程中,通过左旋和右旋操作来保持自平衡。
- 插入修正:在每次插入后,需要对树进行调整以满足红黑树的性质,通过染色、旋转等操作来实现。
这只是一个基本的实现,实际应用应考虑诸如删除操作、更多边界情况处理和优化等。但通过上述代码,你可以初步理解红黑树的概念和机制。