-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSplayTree.py
65 lines (55 loc) · 2.26 KB
/
SplayTree.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
from BST import BstRegular
from constants import sentinel
class BstSplay(BstRegular):
node_type = "splay"
def __init__(self, node=None):
super().__init__(node)
def contains(self, val, current=sentinel):
node_contains_info = self._contains_with_info(val, current)
node_found = node_contains_info.get("flag", False)
node_prior = node_contains_info.get("prior", None)
node = node_contains_info.get("node", None)
if node_found:
self._splay(node)
return node
else:
if node_prior:
self._splay(node_prior)
return None
def _splay(self, node):
if node is None or node is self.root:
return
elif node.parent is self.root:
if node.is_left_child():
self._rotate_right(node.parent) # referred to as zig
elif node.is_right_child():
self._rotate_left(node.parent) # referred to as zag
elif node.parent.parent:
if node.is_left_child() and node.parent.is_left_child():
self._rotate_right(node.parent.parent)
self._rotate_right(node.parent)
elif node.is_right_child() and node.parent.is_right_child():
self._rotate_left(node.parent.parent)
self._rotate_left(node.parent)
elif node.parent.is_left_child() and node.is_right_child():
self._rotate_left(node.parent)
self._rotate_right(node.parent) #node.parent has changed
elif node.parent.is_right_child() and node.is_left_child():
self._rotate_right(node.parent)
self._rotate_left(node.parent) #node.parent has changed
self._splay(node)
def insert(self, val):
node = super().insert(val)
if node:
self._splay(node)
return node
else:
return None
def remove(self, val):
if self.root:
node_remove_info = self._remove_with_info(val)
node_remove_flag = node_remove_info.get("flag", False)
node_prior = node_remove_info.get("prior", None)
if node_remove_flag:
self._splay(node_prior.parent)
return node_remove_flag