1
1
/*
2
- * Splay Tree
2
+ * Splay Tree
3
3
*
4
4
* Based on Binary Search Tree Implementation written by Nicolas Ameghino and Matthijs Hollemans for Swift Algorithms Club
5
5
* https://github.com/raywenderlich/swift-algorithm-club/blob/master/Binary%20Search%20Tree
8
8
*/
9
9
10
10
/**
11
- Represent the 3 possible operations (combinations of rotations) that
12
- could be performed during the Splay phase in Splay Trees
11
+ Represent the 3 possible operations (combinations of rotations) that
12
+ could be performed during the Splay phase in Splay Trees
13
13
14
- - zigZag Left child of a right child OR right child of a left child
15
- - zigZig Left child of a left child OR right child of a right child
16
- - zig Only 1 parent and that parent is the root
14
+ - zigZag Left child of a right child OR right child of a left child
15
+ - zigZig Left child of a left child OR right child of a right child
16
+ - zig Only 1 parent and that parent is the root
17
17
18
18
*/
19
19
public enum SplayOperation {
@@ -23,10 +23,10 @@ public enum SplayOperation {
23
23
24
24
25
25
/**
26
- Splay the given node up to the root of the tree
26
+ Splay the given node up to the root of the tree
27
27
28
- - Parameters:
29
- - node SplayTree node to move up to the root
28
+ - Parameters:
29
+ - node SplayTree node to move up to the root
30
30
*/
31
31
public static func splay< T: Comparable > ( node: Node < T > ) {
32
32
@@ -36,13 +36,13 @@ public enum SplayOperation {
36
36
}
37
37
38
38
/**
39
- Compares the node and its parent and determine
40
- if the rotations should be performed in a zigZag, zigZig or zig case.
39
+ Compares the node and its parent and determine
40
+ if the rotations should be performed in a zigZag, zigZig or zig case.
41
41
42
- - Parmeters:
43
- - forNode SplayTree node to be checked
44
- - Returns
45
- - Operation Case zigZag - zigZig - zig
42
+ - Parmeters:
43
+ - forNode SplayTree node to be checked
44
+ - Returns
45
+ - Operation Case zigZag - zigZig - zig
46
46
*/
47
47
public static func operation< T: Comparable > ( forNode node: Node < T > ) -> SplayOperation {
48
48
@@ -56,33 +56,33 @@ public enum SplayOperation {
56
56
}
57
57
58
58
/**
59
- Applies the rotation associated to the case
60
- Modifying the splay tree and briging the received node further to the top of the tree
59
+ Applies the rotation associated to the case
60
+ Modifying the splay tree and briging the received node further to the top of the tree
61
61
62
- - Parameters:
63
- - onNode Node to splay up. Should be alwayas the node that needs to be splayed, neither its parent neither it's grandparent
62
+ - Parameters:
63
+ - onNode Node to splay up. Should be alwayas the node that needs to be splayed, neither its parent neither it's grandparent
64
64
*/
65
65
public func apply< T: Comparable > ( onNode node: Node < T > ) {
66
66
switch self {
67
67
case . zigZag:
68
68
assert ( node. parent != nil && node. parent!. parent != nil , " Should be at least 2 nodes up in the tree " )
69
69
rotate ( child: node, parent: node. parent!)
70
70
rotate ( child: node, parent: node. parent!)
71
-
71
+
72
72
case . zigZig:
73
73
assert ( node. parent != nil && node. parent!. parent != nil , " Should be at least 2 nodes up in the tree " )
74
74
rotate ( child: node. parent!, parent: node. parent!. parent!)
75
75
rotate ( child: node, parent: node. parent!)
76
-
76
+
77
77
case . zig:
78
78
assert ( node. parent != nil && node. parent!. parent == nil , " There should be a parent which is the root " )
79
79
rotate ( child: node, parent: node. parent!)
80
80
}
81
81
}
82
82
83
83
/**
84
- Performs a single rotation from a node to its parent
85
- re-arranging the children properly
84
+ Performs a single rotation from a node to its parent
85
+ re-arranging the children properly
86
86
*/
87
87
public func rotate< T: Comparable > ( child: Node < T > , parent: Node < T > ) {
88
88
@@ -95,41 +95,41 @@ public enum SplayOperation {
95
95
grandchildToMode = child. right
96
96
parent. left = grandchildToMode
97
97
grandchildToMode? . parent = parent
98
-
98
+
99
99
let grandParent = parent. parent
100
100
child. parent = grandParent
101
-
101
+
102
102
if parent. isLeftChild {
103
103
grandParent? . left = child
104
104
} else {
105
105
grandParent? . right = child
106
106
}
107
-
107
+
108
108
child. right = parent
109
109
parent. parent = child
110
-
111
-
110
+
111
+
112
112
} else {
113
113
114
114
grandchildToMode = child. left
115
115
parent. right = grandchildToMode
116
116
grandchildToMode? . parent = parent
117
-
117
+
118
118
let grandParent = parent. parent
119
119
child. parent = grandParent
120
-
120
+
121
121
if parent. isLeftChild {
122
122
grandParent? . left = child
123
123
} else {
124
124
grandParent? . right = child
125
125
}
126
-
126
+
127
127
child. left = parent
128
128
parent. parent = child
129
-
129
+
130
130
}
131
131
132
-
132
+
133
133
}
134
134
}
135
135
@@ -183,27 +183,31 @@ public class Node<T: Comparable> {
183
183
}
184
184
185
185
public class SplayTree < T: Comparable > {
186
-
186
+
187
187
internal var root : Node < T > ?
188
188
189
189
var value : T ? {
190
190
return root? . value
191
191
}
192
-
192
+
193
193
//MARK: - Initializer
194
194
195
195
public init ( value: T ) {
196
196
self . root = Node ( value: value)
197
197
}
198
198
199
199
public func insert( value: T ) {
200
- root = root? . insert ( value: value)
200
+ if let root = root {
201
+ self . root = root. insert ( value: value)
202
+ } else {
203
+ root = Node ( value: value)
204
+ }
201
205
}
202
206
203
207
public func remove( value: T ) {
204
208
root = root? . remove ( value: value)
205
209
}
206
-
210
+
207
211
public func search( value: T ) -> Node < T > ? {
208
212
root = root? . search ( value: value)
209
213
return root
@@ -229,10 +233,10 @@ extension Node {
229
233
Inserts a new element into the node tree.
230
234
231
235
- Parameters:
232
- - value T value to be inserted. Will be splayed to the root position
236
+ - value T value to be inserted. Will be splayed to the root position
233
237
234
238
- Returns:
235
- - Node inserted
239
+ - Node inserted
236
240
*/
237
241
public func insert( value: T ) -> Node {
238
242
if let selfValue = self . value {
@@ -275,14 +279,14 @@ extension Node {
275
279
276
280
/*
277
281
Deletes the given node from the nodes tree.
278
- Return the new tree generated by the removal.
282
+ Return the new tree generated by the removal.
279
283
The removed node (not necessarily the one containing the value), will be splayed to the root.
280
284
281
285
- Parameters:
282
- - value To be removed
286
+ - value To be removed
283
287
284
288
- Returns:
285
- - Node Resulting from the deletion and the splaying of the removed node
289
+ - Node Resulting from the deletion and the splaying of the removed node
286
290
287
291
*/
288
292
public func remove( value: T ) -> Node < T > ? {
@@ -302,19 +306,29 @@ extension Node {
302
306
303
307
parentToSplay = replacement. parent
304
308
305
- } else {
309
+ } else if self . parent != nil {
306
310
parentToSplay = self . parent
311
+ } else {
312
+ parentToSplay = replacement
307
313
}
308
314
309
315
} else {
310
316
// This node only has a left child. The left child replaces the node.
311
317
replacement = left
312
- parentToSplay = parent
318
+ if self . parent != nil {
319
+ parentToSplay = self . parent
320
+ } else {
321
+ parentToSplay = replacement
322
+ }
313
323
}
314
324
} else if let right = right {
315
325
// This node only has a right child. The right child replaces the node.
316
326
replacement = right
317
- parentToSplay = parent
327
+ if self . parent != nil {
328
+ parentToSplay = self . parent
329
+ } else {
330
+ parentToSplay = replacement
331
+ }
318
332
} else {
319
333
// This node has no children. We just disconnect it from its parent.
320
334
replacement = nil
@@ -332,7 +346,7 @@ extension Node {
332
346
parent = nil
333
347
left = nil
334
348
right = nil
335
-
349
+
336
350
return parentToSplay
337
351
338
352
} else if let v = self . value, value < v {
0 commit comments