Skip to content

Commit 9da711d

Browse files
author
barbara
committed
Fixes for root removal & insertions with nil root
1 parent 4aaec9d commit 9da711d

File tree

2 files changed

+78
-50
lines changed

2 files changed

+78
-50
lines changed

Splay Tree/SplayTree.playground/Sources/SplayTree.swift

+60-46
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Splay Tree
2+
* Splay Tree
33
*
44
* Based on Binary Search Tree Implementation written by Nicolas Ameghino and Matthijs Hollemans for Swift Algorithms Club
55
* https://github.com/raywenderlich/swift-algorithm-club/blob/master/Binary%20Search%20Tree
@@ -8,12 +8,12 @@
88
*/
99

1010
/**
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
1313

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
1717

1818
*/
1919
public enum SplayOperation {
@@ -23,10 +23,10 @@ public enum SplayOperation {
2323

2424

2525
/**
26-
Splay the given node up to the root of the tree
26+
Splay the given node up to the root of the tree
2727

28-
- Parameters:
29-
- node SplayTree node to move up to the root
28+
- Parameters:
29+
- node SplayTree node to move up to the root
3030
*/
3131
public static func splay<T: Comparable>(node: Node<T>) {
3232

@@ -36,13 +36,13 @@ public enum SplayOperation {
3636
}
3737

3838
/**
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.
4141

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
4646
*/
4747
public static func operation<T: Comparable>(forNode node: Node<T>) -> SplayOperation {
4848

@@ -56,33 +56,33 @@ public enum SplayOperation {
5656
}
5757

5858
/**
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
6161

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
6464
*/
6565
public func apply<T: Comparable>(onNode node: Node<T>) {
6666
switch self {
6767
case .zigZag:
6868
assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree")
6969
rotate(child: node, parent: node.parent!)
7070
rotate(child: node, parent: node.parent!)
71-
71+
7272
case .zigZig:
7373
assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree")
7474
rotate(child: node.parent!, parent: node.parent!.parent!)
7575
rotate(child: node, parent: node.parent!)
76-
76+
7777
case .zig:
7878
assert(node.parent != nil && node.parent!.parent == nil, "There should be a parent which is the root")
7979
rotate(child: node, parent: node.parent!)
8080
}
8181
}
8282

8383
/**
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
8686
*/
8787
public func rotate<T: Comparable>(child: Node<T>, parent: Node<T>) {
8888

@@ -95,41 +95,41 @@ public enum SplayOperation {
9595
grandchildToMode = child.right
9696
parent.left = grandchildToMode
9797
grandchildToMode?.parent = parent
98-
98+
9999
let grandParent = parent.parent
100100
child.parent = grandParent
101-
101+
102102
if parent.isLeftChild {
103103
grandParent?.left = child
104104
} else {
105105
grandParent?.right = child
106106
}
107-
107+
108108
child.right = parent
109109
parent.parent = child
110-
111-
110+
111+
112112
} else {
113113

114114
grandchildToMode = child.left
115115
parent.right = grandchildToMode
116116
grandchildToMode?.parent = parent
117-
117+
118118
let grandParent = parent.parent
119119
child.parent = grandParent
120-
120+
121121
if parent.isLeftChild {
122122
grandParent?.left = child
123123
} else {
124124
grandParent?.right = child
125125
}
126-
126+
127127
child.left = parent
128128
parent.parent = child
129-
129+
130130
}
131131

132-
132+
133133
}
134134
}
135135

@@ -183,27 +183,31 @@ public class Node<T: Comparable> {
183183
}
184184

185185
public class SplayTree<T: Comparable> {
186-
186+
187187
internal var root: Node<T>?
188188

189189
var value: T? {
190190
return root?.value
191191
}
192-
192+
193193
//MARK: - Initializer
194194

195195
public init(value: T) {
196196
self.root = Node(value:value)
197197
}
198198

199199
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+
}
201205
}
202206

203207
public func remove(value: T) {
204208
root = root?.remove(value: value)
205209
}
206-
210+
207211
public func search(value: T) -> Node<T>? {
208212
root = root?.search(value: value)
209213
return root
@@ -229,10 +233,10 @@ extension Node {
229233
Inserts a new element into the node tree.
230234

231235
- 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
233237

234238
- Returns:
235-
- Node inserted
239+
- Node inserted
236240
*/
237241
public func insert(value: T) -> Node {
238242
if let selfValue = self.value {
@@ -275,14 +279,14 @@ extension Node {
275279

276280
/*
277281
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.
279283
The removed node (not necessarily the one containing the value), will be splayed to the root.
280284

281285
- Parameters:
282-
- value To be removed
286+
- value To be removed
283287

284288
- 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
286290

287291
*/
288292
public func remove(value: T) -> Node<T>? {
@@ -302,19 +306,29 @@ extension Node {
302306

303307
parentToSplay = replacement.parent
304308

305-
} else {
309+
} else if self.parent != nil {
306310
parentToSplay = self.parent
311+
} else {
312+
parentToSplay = replacement
307313
}
308314

309315
} else {
310316
// This node only has a left child. The left child replaces the node.
311317
replacement = left
312-
parentToSplay = parent
318+
if self.parent != nil {
319+
parentToSplay = self.parent
320+
} else {
321+
parentToSplay = replacement
322+
}
313323
}
314324
} else if let right = right {
315325
// This node only has a right child. The right child replaces the node.
316326
replacement = right
317-
parentToSplay = parent
327+
if self.parent != nil {
328+
parentToSplay = self.parent
329+
} else {
330+
parentToSplay = replacement
331+
}
318332
} else {
319333
// This node has no children. We just disconnect it from its parent.
320334
replacement = nil
@@ -332,7 +346,7 @@ extension Node {
332346
parent = nil
333347
left = nil
334348
right = nil
335-
349+
336350
return parentToSplay
337351

338352
} else if let v = self.value, value < v {

Splay Tree/SplayTree.swift

+18-4
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,11 @@ public class SplayTree<T: Comparable> {
197197
}
198198

199199
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+
}
201205
}
202206

203207
public func remove(value: T) {
@@ -302,19 +306,29 @@ extension Node {
302306

303307
parentToSplay = replacement.parent
304308

305-
} else {
309+
} else if self.parent != nil {
306310
parentToSplay = self.parent
311+
} else {
312+
parentToSplay = replacement
307313
}
308314

309315
} else {
310316
// This node only has a left child. The left child replaces the node.
311317
replacement = left
312-
parentToSplay = parent
318+
if self.parent != nil {
319+
parentToSplay = self.parent
320+
} else {
321+
parentToSplay = replacement
322+
}
313323
}
314324
} else if let right = right {
315325
// This node only has a right child. The right child replaces the node.
316326
replacement = right
317-
parentToSplay = parent
327+
if self.parent != nil {
328+
parentToSplay = self.parent
329+
} else {
330+
parentToSplay = replacement
331+
}
318332
} else {
319333
// This node has no children. We just disconnect it from its parent.
320334
replacement = nil

0 commit comments

Comments
 (0)