Skip to content

Commit 914cf09

Browse files
committed
Implemented isEmpty and elements properties, contains(element:, tree) -> Bool and constructEmpty() -> BinaryTree static methods, refactored the data structure and added usage examples
1 parent 0447144 commit 914cf09

File tree

1 file changed

+54
-2
lines changed
  • Data Structures.playground/Pages/BinaryTree.xcplaygroundpage

1 file changed

+54
-2
lines changed

Data Structures.playground/Pages/BinaryTree.xcplaygroundpage/Contents.swift

+54-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22

33
import Foundation
44

5-
indirect enum BinaryTree<T> {
5+
enum BinaryTree<T> where T : Comparable {
6+
7+
// MARK: - Cases
8+
69
case empty
7-
case node(BinaryTree, T, BinaryTree)
10+
indirect case node(BinaryTree, T, BinaryTree)
11+
12+
// MARK: - Properties
813

914
var count: Int {
1015
switch self {
@@ -14,6 +19,45 @@ indirect enum BinaryTree<T> {
1419
return 0
1520
}
1621
}
22+
23+
var isEmpty: Bool {
24+
switch self {
25+
case .empty:
26+
return true
27+
case .node(_, _, _):
28+
return false
29+
}
30+
}
31+
32+
var elements: [T] {
33+
switch self {
34+
case .empty:
35+
return []
36+
case .node(let left, let element, let right):
37+
return left.elements + [element] + right.elements
38+
}
39+
}
40+
41+
// MARK: - Static methods
42+
43+
static func contains(element: T, tree: BinaryTree<T>) -> Bool {
44+
switch tree {
45+
case .empty:
46+
return false
47+
case .node(let left, let item, let right):
48+
if element < item {
49+
return contains(element: element, tree: left)
50+
} else if element > item {
51+
return contains(element: element, tree: right)
52+
}
53+
return true
54+
}
55+
}
56+
57+
58+
static func constructEmpty() -> BinaryTree {
59+
return .empty
60+
}
1761
}
1862

1963
//: There are several ways how Binary Trees can be constructed. Classic approach is to use reference types e.g. classes. The implementation is pretty similar to the Tree data structure that is implemented in this playground file. However we used a different approach - value types... well sort of. Swift has several value types: structures (aka struct) and enumeration types (aka enum). In Swift enumeration type has many cool features and their practical application usage is far more extended and advanced in comparison to Java or Objective C for example. You may think that it sounds a bit weird... and you will be right. Value types have fixed size, meaning that compiler knows in advance the size of a struct or enum type. However when building recursion compiler does not have information about the size of the type. The last two mentioned conditions contradict each other, so we need to tell the compiler about our intentions. Swift has such mechanims and a special keyword called `indirect`. `Indirect` keyword introduces a layer of indirection behind the scenes which allows us to use value cases or whole enumeration types recursiveley. You need to note that this keyword only works with enums. Structs do not support this feature.
@@ -64,6 +108,14 @@ let finalTree = BinaryTree.node(tree2, "+", treeMult)
64108

65109
print(finalTree)
66110

111+
let containsThree = BinaryTree.contains(element: "3", tree: finalTree)
112+
print(containsThree)
113+
114+
let containsFour = BinaryTree.contains(element: "4", tree: finalTree)
115+
print(containsFour)
116+
117+
let treeElementsArray = finalTree.elements
118+
print(treeElementsArray)
67119

68120
//: In order to properly construct Binary Tree you need to start building the tree by layers. The means the first thing you need to do is to draw the tree and split every single operation into separate layer. Multiplying 5 and 3 is the first operation that happens, that is why we compose this operation separately and form a Binary Tree node separately. Then we define 2 as a separate leaf node and add it to the first layer, which results into a final tree node that contains all the nodes.
69121

0 commit comments

Comments
 (0)