实现红黑树
时间: 2023-06-29 21:05:40 浏览: 111
红黑树是一种自平衡二叉搜索树,它的插入、删除和查找操作的时间复杂度都是 O(log n)。其中,n 是树中节点的数量。
红黑树的特点:
1. 每个节点都是红色或黑色。
2. 根节点是黑色的。
3. 每个叶子节点(NIL节点,空节点)是黑色的。
4. 如果一个节点是红色的,则它的两个子节点都是黑色的。
5. 对于每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。
下面是红黑树的实现:
```python
class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
self.parent = None
self.color = 1 # 1 for red, 0 for black
class RedBlackTree:
def __init__(self):
self.nil = Node(None)
self.nil.color = 0
self.root = self.nil
def insert(self, key):
node = Node(key)
node.parent = None
node.left = self.nil
node.right = self.nil
node.color = 1
y = None
x = self.root
while x != self.nil:
y = x
if node.key < x.key:
x = x.left
else:
x = x.right
node.parent = y
if y is None:
self.root = node
elif node.key < y.key:
y.left = node
else:
y.right = node
if node.parent is None:
node.color = 0
return
if node.parent.parent is None:
return
self.fix_insert(node)
def fix_insert(self, node):
while node.parent.color == 1:
if node.parent == node.parent.parent.right:
u = node.parent.parent.left
if u.color == 1:
u.color = 0
node.parent.color = 0
node.parent.parent.color = 1
node = node.parent.parent
else:
if node == node.parent.left:
node = node.parent
self.right_rotate(node)
node.parent.color = 0
node.parent.parent.color = 1
self.left_rotate(node.parent.parent)
else:
u = node.parent.parent.right
if u.color == 1:
u.color = 0
node.parent.color = 0
node.parent.parent.color = 1
node = node.parent.parent
else:
if node == node.parent.right:
node = node.parent
self.left_rotate(node)
node.parent.color = 0
node.parent.parent.color = 1
self.right_rotate(node.parent.parent)
if node == self.root:
break
self.root.color = 0
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, 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:
self.root = y
elif x == x.parent.right:
x.parent.right = y
else:
x.parent.left = y
y.right = x
x.parent = y
def inorder(self, root):
if root == self.nil:
return
self.inorder(root.left)
print(root.key, end=" ")
self.inorder(root.right)
def search(self, key):
return self.search_helper(self.root, key)
def search_helper(self, node, key):
if node == self.nil or key == node.key:
return node
if key < node.key:
return self.search_helper(node.left, key)
return self.search_helper(node.right, key)
def delete(self, key):
self.delete_node_helper(self.root, key)
def fix_delete(self, x):
while x != self.root and x.color == 0:
if x == x.parent.left:
sib = x.parent.right
if sib.color == 1:
sib.color = 0
x.parent.color = 1
self.left_rotate(x.parent)
sib = x.parent.right
if sib.left.color == 0 and sib.right.color == 0:
sib.color = 1
x = x.parent
else:
if sib.right.color == 0:
sib.left.color = 0
sib.color = 1
self.right_rotate(sib)
sib = x.parent.right
sib.color = x.parent.color
x.parent.color = 0
sib.right.color = 0
self.left_rotate(x.parent)
x = self.root
else:
sib = x.parent.left
if sib.color == 1:
sib.color = 0
x.parent.color = 1
self.right_rotate(x.parent)
sib = x.parent.left
if sib.right.color == 0 and sib.right.color == 0:
sib.color = 1
x = x.parent
else:
if sib.left.color == 0:
sib.right.color = 0
sib.color = 1
self.left_rotate(sib)
sib = x.parent.left
sib.color = x.parent.color
x.parent.color = 0
sib.left.color = 0
self.right_rotate(x.parent)
x = self.root
x.color = 0
def minimum(self, node):
while node.left != self.nil:
node = node.left
return node
def delete_node_helper(self, node, key):
z = self.nil
while node != self.nil:
if node.key == key:
z = node
if node.key <= key:
node = node.right
else:
node = node.left
if z == self.nil:
print("Couldn't find key in the tree")
return
y = z
y_original_color = y.color
if z.left == self.nil:
x = z.right
self.transplant(z, z.right)
elif z.right == self.nil:
x = z.left
self.transplant(z, z.left)
else:
y = self.minimum(z.right)
y_original_color = y.color
x = y.right
if y.parent == z:
x.parent = y
else:
self.transplant(y, y.right)
y.right = z.right
y.right.parent = y
self.transplant(z, y)
y.left = z.left
y.left.parent = y
y.color = z.color
if y_original_color == 0:
self.fix_delete(x)
def transplant(self, u, v):
if u.parent is None:
self.root = v
elif u == u.parent.left:
u.parent.left = v
else:
u.parent.right = v
v.parent = u.parent
```
上面的代码实现了红黑树的插入、删除、查找和中序遍历等操作。其中,`Node` 类表示树中的节点,它包含一个键值 `key`、左右子节点 `left` 和 `right`、父节点 `parent`,以及一个颜色 `color`,用 0 表示黑色,1 表示红色。
`RedBlackTree` 类包含了一个 NIL 节点 `nil` 和根节点 `root`。`insert` 方法用于插入节点,`fix_insert` 方法用于修复插入后可能违反红黑树性质的问题。`delete` 方法用于删除节点,`fix_delete` 方法用于修复删除后可能违反红黑树性质的问题。`transplant` 方法用于节点替换操作。
红黑树的查找操作和普通二叉搜索树相同,这里不再赘述。
阅读全文