Skip to content

Commit 61cf9ef

Browse files
Wesley-Arringtonjiegillet
authored andcommitted
Adding Tree Traversal in Swift (#317)
* Adding Tree Traversal in Swift
1 parent 5edf3f7 commit 61cf9ef

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
class Node {
2+
var value: Int
3+
var children: [Node]?
4+
5+
init(value: Int, children: [Node]) {
6+
self.value = value
7+
self.children = children
8+
}
9+
}
10+
11+
func createTree(numRows: Int, numChildren: Int) -> Node {
12+
let node = Node(value: numRows, children: [])
13+
14+
if numRows > 0 {
15+
for _ in 1...numChildren {
16+
let child = createTree(numRows: numRows-1, numChildren: numChildren)
17+
node.children?.append(child)
18+
}
19+
}
20+
21+
return node
22+
}
23+
24+
func dfsRecursive(node: Node) {
25+
print(node.value)
26+
27+
for child in node.children! {
28+
dfsRecursive(node: child)
29+
}
30+
}
31+
32+
func dfsRecursivePostOrder(node: Node) {
33+
for child in node.children! {
34+
dfsRecursivePostOrder(node: child)
35+
}
36+
37+
print(node.value)
38+
}
39+
40+
func dfsRecursiveInOrderBinary(node: Node) {
41+
if node.children?.count == 2 {
42+
dfsRecursiveInOrderBinary(node: node.children![0])
43+
print(node.value)
44+
dfsRecursiveInOrderBinary(node: node.children![1])
45+
} else if node.children?.count == 1 {
46+
dfsRecursiveInOrderBinary(node: node.children![0])
47+
print(node.value)
48+
} else if node.children?.count == 0 {
49+
print(node.value)
50+
} else {
51+
print("Not a binary tree!")
52+
}
53+
}
54+
55+
func dfsStack(node: Node) {
56+
var stack = [node]
57+
var temp: Node
58+
59+
while stack.count > 0 {
60+
temp = stack.popLast()!
61+
print(temp.value)
62+
63+
for child in temp.children! {
64+
stack.append(child)
65+
}
66+
}
67+
}
68+
69+
func bfsQueue(node: Node) {
70+
var queue = [node]
71+
var temp: Node
72+
73+
while queue.count > 0 {
74+
temp = queue.remove(at: 0)
75+
print(temp.value)
76+
77+
for child in temp.children! {
78+
queue.append(child)
79+
}
80+
}
81+
}
82+
83+
func main() {
84+
let root = createTree(numRows: 3, numChildren: 3)
85+
86+
print("Using recursive DFS:")
87+
dfsRecursive(node: root)
88+
89+
print("Using recursive postorder DFS:")
90+
dfsRecursivePostOrder(node: root)
91+
92+
print("Using stack-based DFS:")
93+
dfsStack(node: root)
94+
95+
print("Using queue-based BFS:")
96+
bfsQueue(node: root)
97+
98+
let rootBinary = createTree(numRows: 3, numChildren: 2)
99+
100+
print("Using In-order DFS:")
101+
dfsRecursiveInOrderBinary(node: rootBinary)
102+
}
103+
104+
main()

contents/tree_traversal/tree_traversal.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ This has not been implemented in your chosen language, so here is the Julia code
2626
[import:4-7, lang:"rust"](code/rust/tree.rs)
2727
{% sample lang="hs"%}
2828
[import:1-3, lang:"haskell"](code/haskell/TreeTraversal.hs)
29+
{% sample lang="swift"%}
30+
[import:1-9, lang:"swift"](code/swift/tree.swift)
2931
{% endmethod %}
3032

3133
Because of this, the most straightforward way to traverse the tree might be recursive. This naturally leads us to the Depth-First Search (DFS) method:
@@ -54,6 +56,8 @@ Because of this, the most straightforward way to traverse the tree might be recu
5456
[import:9-15 lang:"rust"](code/rust/tree.rs)
5557
{% sample lang="hs"%}
5658
[import:5-6, lang:"haskell"](code/haskell/TreeTraversal.hs)
59+
{% sample lang="swift"%}
60+
[import:24-30, lang:"swift"](code/swift/tree.swift)
5761
{% endmethod %}
5862

5963
At least to me, this makes a lot of sense. We fight recursion with recursion! First, we first output the node we are on and then we call `DFS_recursive(...)` on each of its children nodes. This method of tree traversal does what its name implies: it goes to the depths of the tree first before going through the rest of the branches. In this case, the ordering looks like:
@@ -91,6 +95,8 @@ This has not been implemented in your chosen language, so here is the Julia code
9195
[import:17-23, lang:"rust"](code/rust/tree.rs)
9296
{% sample lang="hs"%}
9397
[import:8-9, lang:"haskell"](code/haskell/TreeTraversal.hs)
98+
{% sample lang="swift"%}
99+
[import:32-38, lang:"swift"](code/swift/tree.swift)
94100
{% endmethod %}
95101

96102
<p>
@@ -123,6 +129,8 @@ This has not been implemented in your chosen language, so here is the Julia code
123129
[import:25-38, lang:"rust"](code/rust/tree.rs)
124130
{% sample lang="hs"%}
125131
[import:11-15, lang:"haskell"](code/haskell/TreeTraversal.hs)
132+
{% sample lang="swift"%}
133+
[import:40-53, lang:"swift"](code/swift/tree.swift)
126134
{% endmethod %}
127135

128136
<p>
@@ -165,6 +173,8 @@ In code, it looks like this:
165173
{% sample lang="hs"%}
166174
This has not been implemented in your chosen language, so here is the Julia code
167175
[import:45-56, lang:"julia"](code/julia/Tree.jl)
176+
{% sample lang="swift"%}
177+
[import:55-67, lang:"swift"](code/swift/tree.swift)
168178
{% endmethod %}
169179

170180
All this said, there are a few details about DFS that might not be idea, depending on the situation. For example, if we use DFS on an incredibly long tree, we will spend a lot of time going further and further down a single branch without searching the rest of the data structure. In addition, it is not the natural way humans would order a tree if asked to number all the nodes from top to bottom. I would argue a more natural traversal order would look something like this:
@@ -198,6 +208,8 @@ And this is exactly what Breadth-First Search (BFS) does! On top of that, it can
198208
[import:49-57, lang:"rust"](code/rust/tree.rs)
199209
{% sample lang="hs"%}
200210
[import:17-20, lang:"haskell"](code/haskell/TreeTraversal.hs)
211+
{% sample lang="swift"%}
212+
[import:69-81, lang:"swift"](code/swift/tree.swift)
201213
{% endmethod %}
202214

203215
## Example Code
@@ -233,6 +245,8 @@ The code snippets were taken from this [Scratch project](https://scratch.mit.edu
233245
[import, lang:"rust"](code/rust/tree.rs)
234246
{% sample lang="hs"%}
235247
[import, lang:"haskell"](code/haskell/TreeTraversal.hs)
248+
{% sample lang="swift"%}
249+
[import, lang:"swift"](code/swift/tree.swift)
236250
{% endmethod %}
237251

238252

0 commit comments

Comments
 (0)