-
Notifications
You must be signed in to change notification settings - Fork 66
/
pointer_tree.py
154 lines (143 loc) · 4.79 KB
/
pointer_tree.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env python
from rb_tree import RbNode, RbTree
class pointer_node(RbNode):
def __init__(self, key, p, left, right, color, minimum, maximum, predecessor, successor):
RbNode.__init__(self, key, p, left, right, color)
self.minimum = minimum
self.maximum = maximum
self.predecessor = predecessor
self.successor = successor
class pointer_tree(RbTree):
negative_infinity = pointer_node(
float("-Inf"), None, None, None, 1, None, None, None, None)
positive_infinity = pointer_node(
float("Inf"), None, None, None, 1, None, None, None, None)
nil = pointer_node(None, None, None, None, 1,
negative_infinity, positive_infinity, None, None)
root = nil
def __init__(self, values):
if isinstance(values, list):
for i in values:
self.insert(pointer_node(i, None, None,
None, 0, None, None, None, None))
else:
print("Not invalid argument")
def insert(self, z):
y = self.nil
x = self.root
while x != self.nil:
y = x
if z.key <= x.key:
if z.key < x.minimum.key:
x.minimum = z
# update predecessor attribute of all z's ancestors except z's parent since z inherits the predecessor attribute of z's parent
if x.left != self.nil:
if z.key > x.predecessor.key:
x.predecessor = z
x = x.left
else:
if z.key > x.maximum.key:
x.maximum = z
# update successor attribute of all z's ancestors except z's parent since z inherits the successor attribute of z's parent
if x.right != self.nil:
if z.key < x.successor.key:
x.successor = z
x = x.right
if y == self.nil:
self.root = z
z.predecessor = self.negative_infinity
z.successor = self.positive_infinity
elif z.key <= y.key:
y.left = z
z.successor = y
z.predecessor = y.predecessor
y.predecessor = z
else:
y.right = z
z.predecessor = y
z.successor = y.successor
y.successor = z
z.minimum = z
z.maximum = z
z.p = y
z.left = self.nil
z.right = self.nil
z.color = 0 # red
self.insert_fixed(z)
def left_rotate(self, x):
y = x.right
x.right = y.left
if y.left != self.nil:
y.left.p = x
y.p = x.p
if x.p == self.nil:
self.root = y
elif x.p.left == x:
x.p.left = y
else:
x.p.right = y
y.left = x
x.p = y
y.minimum = x.minimum
if x.right == self.nil:
x.maximum = x
else:
x.maximum = x.right.maximum
def right_rotate(self, y):
x = y.left
y.left = x.right
if x.right != self.nil:
x.right.p = y
x.p = y.p
if y.p == self.nil:
self.root = x
elif y.p.right == y:
y.p.right = x
else:
y.p.left = x
x.right = y
y.p = x
x.maximum = y.maximum
if y.left == self.nil:
y.minimum = y
else:
y.minimum = y.left.minimum
def delete(self, z):
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 = z.right.minimum()
y_original_color = y.color
x = y.right
if y.p == z:
x.p = y
else:
self.transplant(y, y.right)
y.right = z.right
y.right.p = y
self.transplant(z, y)
y.left = z.left
y.left.p = y
y.color = z.color
# After we delete z, the only nodes whose predecessor and successor attributes need to be updated are z's successor and z's predecessor
z.predecessor.successor = z.successor
z.successor.predecessor = z.predecessor
traverse = x.p
while traverse != self.nil:
if traverse.left == self.nil:
traverse.minimum = traverse
else:
traverse.minimum = traverse.left.minimum
if traverse.right == self.nil:
traverse.maximum = traverse
else:
traverse.maximum = traverse.right.maximum
traverse = traverse.p
if y_original_color == 1:
self.delete_fixup(x)