Skip to content

Commit 3bef130

Browse files
authored
Merge pull request kodecocodes#628 from JulioBBL/master
Aditions to AVLTree
2 parents 0e361b0 + 952a064 commit 3bef130

File tree

2 files changed

+153
-89
lines changed

2 files changed

+153
-89
lines changed

AVL Tree/AVLTree.swift

Lines changed: 108 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -22,63 +22,63 @@
2222

2323
public class TreeNode<Key: Comparable, Payload> {
2424
public typealias Node = TreeNode<Key, Payload>
25-
26-
var payload: Payload?
27-
28-
fileprivate var key: Key
25+
26+
var payload: Payload? // Value held by the node
27+
28+
fileprivate var key: Key // Node's name
2929
internal var leftChild: Node?
3030
internal var rightChild: Node?
3131
fileprivate var height: Int
32-
fileprivate weak var parent: Node?
33-
32+
weak fileprivate var parent: Node?
33+
3434
public init(key: Key, payload: Payload?, leftChild: Node?, rightChild: Node?, parent: Node?, height: Int) {
3535
self.key = key
3636
self.payload = payload
3737
self.leftChild = leftChild
3838
self.rightChild = rightChild
3939
self.parent = parent
4040
self.height = height
41-
41+
4242
self.leftChild?.parent = self
4343
self.rightChild?.parent = self
4444
}
45-
45+
4646
public convenience init(key: Key, payload: Payload?) {
4747
self.init(key: key, payload: payload, leftChild: nil, rightChild: nil, parent: nil, height: 1)
4848
}
49-
49+
5050
public convenience init(key: Key) {
5151
self.init(key: key, payload: nil)
5252
}
53-
53+
5454
var isRoot: Bool {
5555
return parent == nil
5656
}
57-
57+
5858
var isLeaf: Bool {
5959
return rightChild == nil && leftChild == nil
6060
}
61-
61+
6262
var isLeftChild: Bool {
6363
return parent?.leftChild === self
6464
}
65-
65+
6666
var isRightChild: Bool {
6767
return parent?.rightChild === self
6868
}
69-
69+
7070
var hasLeftChild: Bool {
7171
return leftChild != nil
7272
}
73-
73+
7474
var hasRightChild: Bool {
7575
return rightChild != nil
7676
}
77-
77+
7878
var hasAnyChild: Bool {
7979
return leftChild != nil || rightChild != nil
8080
}
81-
81+
8282
var hasBothChildren: Bool {
8383
return leftChild != nil && rightChild != nil
8484
}
@@ -88,10 +88,10 @@ public class TreeNode<Key: Comparable, Payload> {
8888

8989
open class AVLTree<Key: Comparable, Payload> {
9090
public typealias Node = TreeNode<Key, Payload>
91-
91+
9292
fileprivate(set) var root: Node?
9393
fileprivate(set) var size = 0
94-
94+
9595
public init() { }
9696
}
9797

@@ -101,7 +101,7 @@ extension TreeNode {
101101
public func minimum() -> TreeNode? {
102102
return leftChild?.minimum() ?? self
103103
}
104-
104+
105105
public func maximum() -> TreeNode? {
106106
return rightChild?.maximum() ?? self
107107
}
@@ -112,11 +112,11 @@ extension AVLTree {
112112
get { return search(input: key) }
113113
set { insert(key: key, payload: newValue) }
114114
}
115-
115+
116116
public func search(input: Key) -> Payload? {
117117
return search(key: input, node: root)?.payload
118118
}
119-
119+
120120
fileprivate func search(key: Key, node: Node?) -> Node? {
121121
if let node = node {
122122
if key == node.key {
@@ -142,7 +142,7 @@ extension AVLTree {
142142
}
143143
size += 1
144144
}
145-
145+
146146
private func insert(input: Key, payload: Payload?, node: Node) {
147147
if input < node.key {
148148
if let child = node.leftChild {
@@ -152,7 +152,7 @@ extension AVLTree {
152152
node.leftChild = child
153153
balance(node: child)
154154
}
155-
} else {
155+
} else if input != node.key {
156156
if let child = node.rightChild {
157157
insert(input: input, payload: payload, node: child)
158158
} else {
@@ -175,25 +175,25 @@ extension AVLTree {
175175
updateHeightUpwards(node: node.parent)
176176
}
177177
}
178-
178+
179179
fileprivate func lrDifference(node: Node?) -> Int {
180180
let lHeight = node?.leftChild?.height ?? 0
181181
let rHeight = node?.rightChild?.height ?? 0
182182
return lHeight - rHeight
183183
}
184-
184+
185185
fileprivate func balance(node: Node?) {
186186
guard let node = node else {
187187
return
188188
}
189-
189+
190190
updateHeightUpwards(node: node.leftChild)
191191
updateHeightUpwards(node: node.rightChild)
192-
192+
193193
var nodes = [Node?](repeating: nil, count: 3)
194194
var subtrees = [Node?](repeating: nil, count: 4)
195195
let nodeParent = node.parent
196-
196+
197197
let lrFactor = lrDifference(node: node)
198198
if lrFactor > 1 {
199199
// left-left or left-right
@@ -202,7 +202,7 @@ extension AVLTree {
202202
nodes[0] = node
203203
nodes[2] = node.leftChild
204204
nodes[1] = nodes[2]?.leftChild
205-
205+
206206
subtrees[0] = nodes[1]?.leftChild
207207
subtrees[1] = nodes[1]?.rightChild
208208
subtrees[2] = nodes[2]?.rightChild
@@ -212,7 +212,7 @@ extension AVLTree {
212212
nodes[0] = node
213213
nodes[1] = node.leftChild
214214
nodes[2] = nodes[1]?.rightChild
215-
215+
216216
subtrees[0] = nodes[1]?.leftChild
217217
subtrees[1] = nodes[2]?.leftChild
218218
subtrees[2] = nodes[2]?.rightChild
@@ -225,7 +225,7 @@ extension AVLTree {
225225
nodes[1] = node
226226
nodes[2] = node.rightChild
227227
nodes[0] = nodes[2]?.rightChild
228-
228+
229229
subtrees[0] = nodes[1]?.leftChild
230230
subtrees[1] = nodes[2]?.leftChild
231231
subtrees[2] = nodes[0]?.leftChild
@@ -235,7 +235,7 @@ extension AVLTree {
235235
nodes[1] = node
236236
nodes[0] = node.rightChild
237237
nodes[2] = nodes[0]?.leftChild
238-
238+
239239
subtrees[0] = nodes[1]?.leftChild
240240
subtrees[1] = nodes[2]?.leftChild
241241
subtrees[2] = nodes[2]?.rightChild
@@ -246,9 +246,9 @@ extension AVLTree {
246246
balance(node: node.parent)
247247
return
248248
}
249-
249+
250250
// nodes[2] is always the head
251-
251+
252252
if node.isRoot {
253253
root = nodes[2]
254254
root?.parent = nil
@@ -259,25 +259,25 @@ extension AVLTree {
259259
nodeParent?.rightChild = nodes[2]
260260
nodes[2]?.parent = nodeParent
261261
}
262-
262+
263263
nodes[2]?.leftChild = nodes[1]
264264
nodes[1]?.parent = nodes[2]
265265
nodes[2]?.rightChild = nodes[0]
266266
nodes[0]?.parent = nodes[2]
267-
267+
268268
nodes[1]?.leftChild = subtrees[0]
269269
subtrees[0]?.parent = nodes[1]
270270
nodes[1]?.rightChild = subtrees[1]
271271
subtrees[1]?.parent = nodes[1]
272-
272+
273273
nodes[0]?.leftChild = subtrees[2]
274274
subtrees[2]?.parent = nodes[0]
275275
nodes[0]?.rightChild = subtrees[3]
276276
subtrees[3]?.parent = nodes[0]
277-
277+
278278
updateHeightUpwards(node: nodes[1]) // Update height from left
279279
updateHeightUpwards(node: nodes[0]) // Update height from right
280-
280+
281281
balance(node: nodes[2]?.parent)
282282
}
283283
}
@@ -299,11 +299,35 @@ extension AVLTree {
299299
display(node: node.leftChild, level: level + 1)
300300
}
301301
}
302-
302+
303303
public func display(node: Node) {
304304
display(node: node, level: 0)
305305
print("")
306306
}
307+
308+
public func inorder(node: Node?) -> String {
309+
var output = ""
310+
if let node = node {
311+
output = "\(inorder(node: node.leftChild)) \(print("\(node.key) ")) \(inorder(node: node.rightChild))"
312+
}
313+
return output
314+
}
315+
316+
public func preorder(node: Node?) -> String {
317+
var output = ""
318+
if let node = node {
319+
output = "\(preorder(node: node.leftChild)) \(print("\(node.key) ")) \(preorder(node: node.rightChild))"
320+
}
321+
return output
322+
}
323+
324+
public func postorder(node: Node?) -> String {
325+
var output = ""
326+
if let node = node {
327+
output = "\(postorder(node: node.leftChild)) \(print("\(node.key) ")) \(postorder(node: node.rightChild))"
328+
}
329+
return output
330+
}
307331
}
308332

309333
// MARK: - Delete node
@@ -318,7 +342,7 @@ extension AVLTree {
318342
size -= 1
319343
}
320344
}
321-
345+
322346
private func delete(node: Node) {
323347
if node.isLeaf {
324348
// Just remove and balance up
@@ -327,13 +351,13 @@ extension AVLTree {
327351
// just in case
328352
fatalError("Error: tree is invalid.")
329353
}
330-
354+
331355
if node.isLeftChild {
332356
parent.leftChild = nil
333357
} else if node.isRightChild {
334358
parent.rightChild = nil
335359
}
336-
360+
337361
balance(node: parent)
338362
} else {
339363
// at root
@@ -354,6 +378,46 @@ extension AVLTree {
354378
}
355379
}
356380

381+
// MARK: - Advanced Stuff
382+
383+
extension AVLTree {
384+
public func doInOrder(node: Node?, _ completion: (Node) -> Void) {
385+
if let node = node {
386+
doInOrder(node: node.leftChild) { lnode in
387+
completion(lnode)
388+
}
389+
completion(node)
390+
doInOrder(node: node.rightChild) { rnode in
391+
completion(rnode)
392+
}
393+
}
394+
}
395+
396+
public func doInPreOrder(node: Node?, _ completion: (Node) -> Void) {
397+
if let node = node {
398+
completion(node)
399+
doInPreOrder(node: node.leftChild) { lnode in
400+
completion(lnode)
401+
}
402+
doInPreOrder(node: node.rightChild) { rnode in
403+
completion(rnode)
404+
}
405+
}
406+
}
407+
408+
public func doInPostOrder(node: Node?, _ completion: (Node) -> Void) {
409+
if let node = node {
410+
doInPostOrder(node: node.leftChild) { lnode in
411+
completion(lnode)
412+
}
413+
doInPostOrder(node: node.rightChild) { rnode in
414+
completion(rnode)
415+
}
416+
completion(node)
417+
}
418+
}
419+
}
420+
357421
// MARK: - Debugging
358422

359423
extension TreeNode: CustomDebugStringConvertible {

0 commit comments

Comments
 (0)