Skip to content

Commit 9ef25be

Browse files
committed
SplayTree implementation
1 parent f5c2614 commit 9ef25be

File tree

1 file changed

+212
-0
lines changed

1 file changed

+212
-0
lines changed

src/splay_tree.jl

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
mutable struct SplayTreeNode{K}
2+
leftChild::Union{SplayTreeNode{K}, Nothing}
3+
rightChild::Union{SplayTreeNode{K}, Nothing}
4+
parent::Union{SplayTreeNode{K}, Nothing}
5+
dirty::Bool
6+
data::K
7+
8+
SplayTreeNode{K}() where K = new{K}(nothing, nothing, nothing, true)
9+
SplayTreeNode{K}(d::K) where K = new{K}(nothing, nothing, nothing, false, d)
10+
end
11+
12+
SplayTreeNode_or_null{K} = Union{SplayTreeNode{K}, Nothing}
13+
14+
SplayTreeNode(d) = SplayTreeNode{Any}(d)
15+
SplayTreeNode() = SplayTreeNode{Any}()
16+
17+
isdirty(node::SplayTreeNode) = node.dirty
18+
19+
mutable struct SplayTree{K}
20+
root::SplayTreeNode_or_null{K}
21+
22+
SplayTree{K}() where K = new{K}(nothing)
23+
end
24+
25+
SplayTree(d) = SplayTree{Any}(d)
26+
SplayTree() = SplayTree{Any}()
27+
28+
function left_rotate!(tree::SplayTree, node_x::SplayTreeNode)
29+
node_y = node_x.rightChild
30+
node_x.rightChild = node_y.leftChild
31+
if node_y.leftChild != nothing
32+
node_y.leftChild.parent = node_x
33+
end
34+
node_y.parent = node_x.parent
35+
36+
if node_x.parent == nothing
37+
tree.root = node_y
38+
elseif (node_x == node_x.parent.leftChild)
39+
node_x.parent.leftChild = node_y
40+
else
41+
node_x.parent.rightChild = node_y
42+
end
43+
if node_y != nothing
44+
node_y.leftChild = node_x
45+
end
46+
node_x.parent = node_y
47+
end
48+
49+
function right_rotate!(tree::SplayTree, node_x::SplayTreeNode)
50+
node_y = node_x.leftChild
51+
node_x.leftChild = node_y.rightChild
52+
if node_y.rightChild != nothing
53+
node_y.rightChild.parent = node_x
54+
end
55+
node_y.parent = node_x.parent
56+
if node_x.parent == nothing
57+
tree.root = node_y
58+
elseif (node_x == node_x.parent.leftChild)
59+
node_x.parent.leftChild = node_y
60+
else
61+
node_x.parent.rightChild = node_y
62+
end
63+
node_y.rightChild = node_x
64+
node_x.parent = node_y
65+
end
66+
67+
68+
function splay!(tree::SplayTree, node_x::SplayTreeNode)
69+
while !isa(node_x.parent, Nothing)
70+
parent = node_x.parent
71+
grand_parent = node_x.parent.parent
72+
# grand-parent is Null
73+
if isa(grand_parent, Nothing)
74+
# single rotation
75+
if node_x == parent.leftChild
76+
# zig rotation
77+
right_rotate!(tree, node_x.parent)
78+
else
79+
# zag rotation
80+
left_rotate!(tree, node_x.parent)
81+
end
82+
# double rotation
83+
elseif node_x == parent.leftChild && parent == grand_parent.leftChild
84+
# zig-zig rotation
85+
right_rotate!(tree, grand_parent)
86+
right_rotate!(tree, parent)
87+
elseif node_x == parent.rightChild && parent == grand_parent.rightChild
88+
# zag-zag rotation
89+
left_rotate!(tree, grand_parent)
90+
left_rotate!(tree, parent)
91+
elseif node_x == parent.rightChild && parent == grand_parent.leftChild
92+
# zig-zag rotation
93+
left_rotate!(tree, node_x.parent)
94+
right_rotate!(tree, node_x.parent)
95+
else
96+
# zag-zig rotation
97+
right_rotate!(tree, node_x.parent)
98+
left_rotate!(tree, node_x.parent)
99+
end
100+
end
101+
end
102+
103+
function maximum(node::SplayTreeNode)
104+
while !isa(node.rightChild, Nothing)
105+
node = node.rightChild
106+
end
107+
return node
108+
end
109+
110+
function _join(tree::SplayTree ,s::SplayTreeNode_or_null, t::SplayTreeNode_or_null)
111+
if isa(s, Nothing)
112+
return t
113+
elseif isa(t, Nothing)
114+
return s
115+
else
116+
x = maximum(s)
117+
splay!(tree, x)
118+
x.rightChild = t
119+
t.parent = x
120+
return x
121+
end
122+
end
123+
124+
function search_by_node(node::SplayTreeNode_or_null{K}, d::K) where K
125+
while !isa(node, Nothing)
126+
if node.data == d
127+
break
128+
elseif node.data < d
129+
if !isa(node.rightChild, Nothing)
130+
node = node.rightChild
131+
else
132+
break
133+
end
134+
else
135+
if isa(node.leftChild, Nothing)
136+
node = node.leftChild
137+
else
138+
break
139+
end
140+
end
141+
end
142+
return node
143+
end
144+
145+
function search_key(tree::SplayTree{K}, d::K) where K
146+
node = tree.root
147+
if isa(node, Nothing)
148+
return false
149+
else
150+
node = search_by_node(node, d)
151+
isa(node, Nothing) && return false
152+
is_found = (node.data == d)
153+
is_found && splay!(tree, node)
154+
return is_found
155+
end
156+
end
157+
158+
function delete!(tree::SplayTree{K}, d::K) where K
159+
node = tree.root
160+
x = search_by_node(node, d)
161+
isa(x, Nothing) && return tree
162+
t = nothing
163+
s = nothing
164+
165+
splay!(tree, x)
166+
167+
if !isa(x.rightChild, Nothing)
168+
t = x.rightChild
169+
t.parent = nothing
170+
end
171+
172+
s = x
173+
s.rightChild = nothing
174+
175+
if !isa(s.leftChild, Nothing)
176+
s.leftChild.parent = nothing
177+
end
178+
179+
tree.root = _join(tree, s.leftChild, t)
180+
return tree
181+
end
182+
183+
function insert!(tree::SplayTree{K}, d::K) where K
184+
is_present = search_by_node(tree.root, d)
185+
if !isa(is_present, Nothing) && (is_present.data == d)
186+
return tree
187+
end
188+
# only unique keys are inserted
189+
node = SplayTreeNode{K}(d)
190+
y = nothing
191+
x = tree.root
192+
193+
while !isa(x, Nothing)
194+
y = x
195+
if node.data > x.data
196+
x = x.rightChild
197+
else
198+
x = x.leftChild
199+
end
200+
end
201+
node.parent = y
202+
203+
if isa(y, Nothing)
204+
tree.root = node
205+
elseif node.data < y.data
206+
y.leftChild = node
207+
else
208+
y.rightChild = node
209+
end
210+
splay!(tree, node)
211+
return tree
212+
end

0 commit comments

Comments
 (0)