Skip to content

Commit c23ee08

Browse files
committed
Merge pull request #84 from prankymat/improve-avl-tree-test
added more test cases to test the validity of the AVL Tree
2 parents 1f5c20e + 21ce7ad commit c23ee08

File tree

3 files changed

+87
-22
lines changed

3 files changed

+87
-22
lines changed

AVL Tree/AVLTree.playground/Sources/AVLTree.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ public class TreeNode<Key: Comparable, Payload> {
2626
public var payload: Payload?
2727

2828
private var key: Key
29-
private var leftChild: Node?
30-
private var rightChild: Node?
29+
internal var leftChild: Node?
30+
internal var rightChild: Node?
3131
private var height: Int
3232
weak private var parent: Node?
3333

@@ -343,6 +343,8 @@ extension AVLTree {
343343
} else if node.isRightChild {
344344
parent.rightChild = nil
345345
}
346+
347+
balance(parent)
346348
} else {
347349
// at root
348350
root = nil

AVL Tree/AVLTree.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ public class TreeNode<Key: Comparable, Payload> {
2626
public var payload: Payload?
2727

2828
private var key: Key
29-
private var leftChild: Node?
30-
private var rightChild: Node?
29+
internal var leftChild: Node?
30+
internal var rightChild: Node?
3131
private var height: Int
3232
weak private var parent: Node?
3333

@@ -343,6 +343,8 @@ extension AVLTree {
343343
} else if node.isRightChild {
344344
parent.rightChild = nil
345345
}
346+
347+
balance(parent)
346348
} else {
347349
// at root
348350
root = nil

AVL Tree/Tests/AVLTreeTests.swift

+79-18
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,61 @@ import XCTest
1111
class AVLTreeTests: XCTestCase {
1212

1313
var tree : AVLTree<Int, String>?
14-
14+
1515
override func setUp() {
1616
super.setUp()
1717

1818
tree = AVLTree()
19-
tree?.insert(1, "A")
20-
tree?.insert(2, "B")
21-
tree?.insert(3, "C")
22-
tree?.insert(4, "D")
2319
}
2420

2521
override func tearDown() {
2622
// Put teardown code here. This method is called after the invocation of each test method in the class.
2723
super.tearDown()
2824
}
29-
25+
26+
func testAVLTreeBalancedAutoPopulate() {
27+
self.tree?.autopopulateWithNodes(10)
28+
29+
do {
30+
try self.tree?.inOrderCheckBalanced(self.tree?.root)
31+
} catch _ {
32+
XCTFail("Tree is not balanced after autopopulate")
33+
}
34+
}
35+
36+
func testAVLTreeBalancedInsert() {
37+
self.tree?.autopopulateWithNodes(5)
38+
39+
for i in 6...10 {
40+
self.tree?.insert(i)
41+
do {
42+
try self.tree?.inOrderCheckBalanced(self.tree?.root)
43+
} catch _ {
44+
XCTFail("Tree is not balanced after inserting " + String(i))
45+
}
46+
}
47+
}
48+
49+
func testAVLTreeBalancedDelete() {
50+
self.tree?.autopopulateWithNodes(5)
51+
52+
for i in 1...6 {
53+
self.tree?.delete(i)
54+
do {
55+
try self.tree?.inOrderCheckBalanced(self.tree?.root)
56+
} catch _ {
57+
XCTFail("Tree is not balanced after deleting " + String(i))
58+
}
59+
}
60+
}
61+
3062
func testEmptyInitialization() {
3163
let tree = AVLTree<Int,String>()
3264

3365
XCTAssertEqual(tree.size, 0)
3466
XCTAssertNil(tree.root)
3567
}
36-
37-
func testNotEmptyInitialization() {
38-
XCTAssertNotNil(self.tree?.root)
39-
XCTAssertNotEqual(self.tree!.size, 0)
40-
}
41-
42-
func testInsertDuplicated() {
43-
self.tree?.insert(1, "A")
44-
XCTAssertEqual(self.tree?.size, 5, "Duplicated elements should be allowed")
45-
}
46-
68+
4769
func testSingleInsertionPerformance() {
4870
self.measureBlock {
4971
self.tree?.insert(5, "E")
@@ -92,6 +114,14 @@ class AVLTreeTests: XCTestCase {
92114
self.tree?.delete(1056)
93115
XCTAssertNil(self.tree?.search(1056), "Key should not exist")
94116
}
117+
118+
func testInsertSize() {
119+
let tree = AVLTree<Int, String>()
120+
for i in 0...5 {
121+
tree.insert(i, "")
122+
XCTAssertEqual(tree.size, i + 1, "Insert didn't update size correctly!")
123+
}
124+
}
95125

96126
func testDelete() {
97127
let permutations = [
@@ -109,9 +139,12 @@ class AVLTreeTests: XCTestCase {
109139
tree.insert(3, "three")
110140
tree.insert(4, "two")
111141
tree.insert(5, "one")
112-
142+
143+
var count = tree.size
113144
for i in p {
114145
tree.delete(i)
146+
count -= 1
147+
XCTAssertEqual(tree.size, count, "Delete didn't update size correctly!")
115148
}
116149
}
117150
}
@@ -126,3 +159,31 @@ extension AVLTree where Key : SignedIntegerType {
126159
}
127160
}
128161
}
162+
163+
enum AVLTreeError: ErrorType {
164+
case NotBalanced
165+
}
166+
167+
extension AVLTree where Key : SignedIntegerType {
168+
func height(node: Node?) -> Int {
169+
if let node = node {
170+
let lHeight = height(node.leftChild)
171+
let rHeight = height(node.rightChild)
172+
173+
return max(lHeight, rHeight) + 1
174+
}
175+
return 0
176+
}
177+
178+
func inOrderCheckBalanced(node: Node?) throws {
179+
if let node = node {
180+
guard abs(height(node.leftChild) - height(node.rightChild)) <= 1 else {
181+
throw AVLTreeError.NotBalanced
182+
}
183+
try inOrderCheckBalanced(node.leftChild)
184+
try inOrderCheckBalanced(node.rightChild)
185+
}
186+
}
187+
}
188+
189+

0 commit comments

Comments
 (0)