伸展树

伸展树(Splay Tree)

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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
import sys


class Node:
def __init__(self, data):
self.data = data
self.parent = None
self.left = None
self.right = None


class SplayTree:
def __init__(self):
self.root = None

def __print_helper(self, current_print, indent, last):
# print the tree structure on the screen
if current_print is not None:
sys.stdout.write(indent)
if last:
sys.stdout.write("R----")
indent += " "
else:
sys.stdout.write("L----")
indent += "| "

print(current_print.data)

self.__print_helper(current_print.left, indent, False)
self.__print_helper(current_print.right, indent, True)

def __search_tree_helper(self, node, key):
if node is None or key == node.data:
return node

if key < node.data:
return self.__search_tree_helper(node.left, key)
return self.__search_tree_helper(node.right, key)

def __delete_node_helper(self, node, key):
x = None
t = None
s = None
while node is not None:
if node.data == key:
x = node

if node.data <= key:
node = node.right
else:
node = node.left

if x is None:
print("Couldn't find key in the tree")
return

# split operation
self.__splay(x)
if x.right is not None:
t = x.right
t.parent = None
else:
t = None

s = x
s.right = None
x = None

# join operation
if s.left is not None:
s.left.parent = None

self.root = self.__join(s.left, t)
s = None

# rotate left at node x
def __left_rotate(self, x):
y = x.right
x.right = y.left
if y.left is not None:
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

# rotate right at node x
def __right_rotate(self, x):
y = x.left
x.left = y.right
if y.right is not None:
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

# Splaying operation. It moves x to the root of the tree
def __splay(self, x):
while x.parent is not None:
if x.parent.parent is None:
if x == x.parent.left:
# zig rotation
self.__right_rotate(x.parent)
else:
# zag rotation
self.__left_rotate(x.parent)
elif x == x.parent.left and x.parent == x.parent.parent.left:
# zig-zig rotation
self.__right_rotate(x.parent.parent)
self.__right_rotate(x.parent)
elif x == x.parent.right and x.parent == x.parent.parent.right:
# zag-zag rotation
self.__left_rotate(x.parent.parent)
self.__left_rotate(x.parent)
elif x == x.parent.right and x.parent == x.parent.parent.left:
# zig-zag rotation
self.__left_rotate(x.parent)
self.__right_rotate(x.parent)
else:
# zag-zig rotation
self.__right_rotate(x.parent)
self.__left_rotate(x.parent)

# joins two trees s and t
def __join(self, s, t):
if s is None:
return t

if t is None:
return s

x = self.maximum(s)
self.__splay(x)
x.right = t
t.parent = x
return x

def __pre_order_helper(self, node):
if node is not None:
sys.stdout.write(node.data + " ")
self.__pre_order_helper(node.left)
self.__pre_order_helper(node.right)

def __in_order_helper(self, node):
if node is not None:
self.__in_order_helper(node.left)
sys.stdout.write(node.data + " ")
self.__in_order_helper(node.right)

def __post_order_helper(self, node):
if node is not None:
self.__post_order_helper(node.left)
self.__post_order_helper(node.right)
sys.stdout.write(node.data + " ")

# Pre-Order traversal
# Node->Left Subtree->Right Subtree
def preorder(self):
self.__pre_order_helper(self.root)

# In-Order traversal
# Left Subtree -> Node -> Right Subtree
def inorder(self):
self.__in_order_helper(self.root)

# Post-Order traversal
# Left Subtree -> Right Subtree -> Node
def postorder(self):
self.__post_order_helper(self.root)

# search the tree for the key k
# and return the corresponding node
def search_tree(self, k):
x = self.__search_tree_helper(self.root, k)
if x is not None:
self.__splay(x)

# find the node with the minimum key
@staticmethod
def minimum(node):
while node.left is not None:
node = node.left
return node

# find the node with the maximum key
@staticmethod
def maximum(node):
while node.right is not None:
node = node.right
return node

# find the successor of a given node
def successor(self, x):
# if the right subtree is not null,
# the successor is the leftmost node in the
# right subtree
if x.right is not None:
return self.minimum(x.right)

# else it is the lowest ancestor of x whose
# left child is also an ancestor of x.
y = x.parent
while y is not None and x == y.right:
x = y
y = y.parent
return y

# find the predecessor of a given node
def predecessor(self, x):
# if the left subtree is not null,
# the predecessor is the rightmost node in the
# left subtree
if x.left is not None:
return self.maximum(x.left)

y = x.parent
while y is not None and x == y.left:
x = y
y = y.parent
return y

# insert the key to the tree in its appropriate position
def insert(self, key):
node = Node(key)
y = None
x = self.root

while x is not None:
y = x
if node.data < x.data:
x = x.left
else:
x = x.right

# y is parent of x
node.parent = y
if y is None:
self.root = node
elif node.data < y.data:
y.left = node
else:
y.right = node
# splay the node
self.__splay(node)

# delete the node from the tree
def delete_node(self, data):
self.__delete_node_helper(self.root, data)

# print the tree structure on the screen
def pretty_print(self):
self.__print_helper(self.root, "", True)

参考资料

Splay Trees


伸展树
https://wangqian0306.github.io/2021/splay_tree/
作者
WangQian
发布于
2021年11月22日
许可协议