红黑树是一种自平衡二叉查找树,具有多种特性确保了它在最坏情况下的操作时间复杂度为O(log n)。本文将通过Python代码实现一个简单的红黑树,并展示其基本的操作方法。
红黑树有以下5个重要性质:
首先定义红黑树的基本结构,并初始化一些属性,如颜色、父节点和子节点等。
class Node:
def __init__(self, key):
self.key = key
self.color = 'RED' # 初始颜色为红色
self.parent = None
self.left = None
self.right = None
class RedBlackTree:
def __init__(self):
self.NIL = Node(None) # 空节点
self.NIL.color = 'BLACK'
self.root = self.NIL
插入新元素时,我们首先将它作为红色节点插入到二叉树中。然后通过一系列旋转和着色调整来恢复红黑树的性质。
def insert(self, key):
node = Node(key)
node.left = self.NIL
node.right = self.NIL
parent = None
current = self.root
while current != self.NIL:
parent = current
if node.key < current.key:
current = current.left
else:
current = current.right
node.parent = parent
if parent is None:
self.root = node # 树为空,直接插入为根节点
elif node.key < parent.key:
parent.left = node
else:
parent.right = node
node.color = 'RED' # 插入时颜色设为红色
self.fix_insert(node)
需要对插入后的红黑树进行调整,使其满足红黑树的性质。
def fix_insert(self, k):
while k.parent.color == 'RED':
if k.parent == k.parent.parent.left:
u = k.parent.parent.right # 叔叔节点
if u.color == 'RED': # 情况1:叔叔是红色的
u.color = 'BLACK'
k.parent.color = 'BLACK'
k.parent.parent.color = 'RED'
k = k.parent.parent
else:
if k == k.parent.right: # 情况2:k是右孩子,且父节点是左子树
k = k.parent
self.left_rotate(k)
# 情况3:k是左孩子,调整后进行一次右旋
k.parent.color = 'BLACK'
k.parent.parent.color = 'RED'
self.right_rotate(k.parent.parent)
else: # 类似的情况2和情况3(叔叔在右子树中)
u = k.parent.parent.left
if u.color == 'RED':
u.color = 'BLACK'
k.parent.color = 'BLACK'
k.parent.parent.color = 'RED'
k = k.parent.parent
else:
if k == k.parent.left: # 情况2,k是左孩子
k = k.parent
self.right_rotate(k)
# 情况3:k是右孩子
k.parent.color = 'BLACK'
k.parent.parent.color = 'RED'
self.left_rotate(k.parent.parent)
if k == self.root:
break
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: # 当x是根节点时,调整根节点
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, x):
y = x.left
x.left = y.right
if y.right != self.NIL:
y.right.parent = x
y.parent = x.parent
if x.parent is None: # 当x是根节点时,调整根节点
self.root = y
elif x == x.parent.right:
x.parent.right = y
else:
x.parent.left = y
y.right = x
x.parent = y
通过上述实现,我们已经完成了红黑树的基本插入操作以及相关的修复逻辑。这些基本操作保证了插入元素后的红黑树仍然满足性质要求。红黑树的实现不仅展示了平衡二叉查找树的思想,也体现了对算法细节的关注和处理。