-
Notifications
You must be signed in to change notification settings - Fork 0
/
redblack-1.py
120 lines (105 loc) · 3.95 KB
/
redblack-1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
class Node:
def __init__(self, data):
self.data = data
self.color = 'RED' # New nodes are always red
self.left = None
self.right = None
self.parent = None
class RedBlackTree:
def __init__(self):
self.NIL_LEAF = Node(None)
self.NIL_LEAF.color = 'BLACK' # NIL nodes are always black
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 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'
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
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 inorder_traversal(self, node):
if node != self.NIL_LEAF:
self.inorder_traversal(node.left)
print(f'{node.data} ({node.color})', end=' ')
self.inorder_traversal(node.right)
# Example usage of the RedBlackTree class:
if __name__ == '__main__':
tree = RedBlackTree()
elements = [20, 15, 25, 10, 5, 1, 17, 22, 27,8,99,101,7,2,33,34,35,103,77,78,79]
for element in elements:
tree.insert(element)
print("Inorder traversal of the Red-Black Tree:")
tree.inorder_traversal(tree.root)