1
1
import Foundation
2
2
3
+ //The root is the top of the Radix Tree
3
4
class Root {
4
5
5
6
var children : [ Edge ]
@@ -8,10 +9,14 @@ class Root {
8
9
children = [ Edge] ( )
9
10
}
10
11
12
+ //The height functions returns the length (in number of edges) of the longest
13
+ // traversal down the tree
11
14
func height( ) -> Int {
15
+ //Base case: no children: the tree has a height of 1
12
16
if children. count == 0 {
13
17
return 1
14
18
}
19
+ //Recursion: find the max height of a root's child and return 1 + that max
15
20
else {
16
21
var max = 1
17
22
for c in children {
@@ -23,11 +28,16 @@ class Root {
23
28
}
24
29
}
25
30
31
+ //The level function returns how far down in the tree a Root/Edge is
32
+ //A root's level is always 0
26
33
func level( ) -> Int {
27
34
return 0
28
35
}
29
36
37
+ //printRoot is a recursive function that prints the tree for debugging/
38
+ // visualization purposes
30
39
func printRoot( ) {
40
+ //Print the first half of the children
31
41
if ( children. count > 1 ) {
32
42
for c in 0 ... children. count/ 2 - 1 {
33
43
children [ c] . printEdge ( )
@@ -37,7 +47,9 @@ class Root {
37
47
else if children. count > 0 {
38
48
children [ 0 ] . printEdge ( )
39
49
}
50
+ //Then print the root
40
51
print ( " ROOT " )
52
+ //Print the second half of the children
41
53
if children. count > 1 {
42
54
for c in children. count/ 2 ... children. count- 1 {
43
55
children [ c] . printEdge ( )
@@ -48,6 +60,7 @@ class Root {
48
60
}
49
61
}
50
62
63
+ //Edges are what actually store the Strings in the tree
51
64
class Edge : Root {
52
65
53
66
var parent : Root ?
@@ -58,27 +71,36 @@ class Edge: Root {
58
71
super. init ( )
59
72
}
60
73
74
+ //The Edge class overrides root's level function
61
75
override
62
76
func level( ) -> Int {
77
+ //Recurse up the tree incrementing level by one until the root is reached
63
78
if parent != nil {
64
79
return 1 + parent!. level ( )
65
80
}
81
+ //If an edge has no parent, it's level is one
82
+ // NOTE: THIS SHOULD NEVER HAPPEN AS THE ROOT IS ALWAYS THE TOP OF THE TREE
66
83
else {
67
84
return 1
68
85
}
69
86
}
70
87
88
+ //Erase erases a specific edge (and all edges below it in the tree)
71
89
func erase( ) {
72
90
self . parent = nil
73
91
if children. count > 0 {
92
+ //For each child, erase it, then remove it from the children array
74
93
for _ in 0 ... children. count- 1 {
75
94
children [ 0 ] . erase ( )
76
95
children. remove ( at: 0 )
77
96
}
78
97
}
79
98
}
80
99
100
+ //printEdge is used in printRoot to print the tree
101
+ // It follows a similar structure to printRoot
81
102
func printEdge( ) {
103
+ //Print the first half of the edge's children
82
104
if children. count > 1 {
83
105
for c in 0 ... children. count/ 2 - 1 {
84
106
children [ c] . printEdge ( )
@@ -87,21 +109,17 @@ class Edge: Root {
87
109
else if children. count > 0 {
88
110
children [ 0 ] . printEdge ( )
89
111
}
112
+ //Tab over once up to the edge's level
90
113
for x in 1 ... level ( ) {
91
114
if x == level ( ) {
92
115
print ( " |------> " , terminator: " " )
93
116
}
94
- else if x == 1 {
95
- print ( " | " , terminator: " " )
96
- }
97
- else if x == level ( ) - 1 {
98
- print ( " | " , terminator: " " )
99
- }
100
117
else {
101
118
print ( " | " , terminator: " " )
102
119
}
103
120
}
104
121
print ( label)
122
+ //Print the second half of the edge's children
105
123
if children. count == 0 {
106
124
for _ in 1 ... level ( ) {
107
125
print ( " | " , terminator: " " )
@@ -124,38 +142,47 @@ class RadixTree {
124
142
root = Root ( )
125
143
}
126
144
145
+ //Returns the height of the tree by calling the root's height function
127
146
func height( ) -> Int {
128
147
return root. height ( ) - 1
129
148
}
130
149
150
+ //Inserts a string into the tree
131
151
func insert( _ str: String ) -> Bool {
132
152
//Account for a blank input
153
+ // The empty string is already in the tree
133
154
if str == " " {
134
155
return false
135
156
}
136
- //Account for an empty tree
137
- if root. children. count == 0 {
138
- root. children. append ( Edge ( str) )
139
- return true
140
- }
157
+ //searchStr is the parameter of the function
158
+ // it will be substringed as the function traverses down the tree
141
159
var searchStr = str
160
+ //currEdge is the current Edge (or Root) in question
142
161
var currEdge = root
143
162
while ( true ) {
144
163
var found = false
164
+ //If the current Edge has no children then the remaining searchStr is
165
+ // created as a child
145
166
if currEdge. children. count == 0 {
146
167
let newEdge = Edge ( searchStr)
147
168
currEdge. children. append ( newEdge)
148
169
newEdge. parent = currEdge
170
+ return true
149
171
}
172
+ //Loop through all of the children
150
173
for e in currEdge. children {
151
- //Get the shared
174
+ //Get the shared prefix betweeen the child in question and the
175
+ // search string
152
176
var shared = sharedPrefix ( searchStr, e. label)
153
177
var index = shared. startIndex
154
- //The search string is equal to the shared string
155
- //so the string already exists in the tree
178
+ //If the search string is equal to the shared string,
179
+ // the string already exists in the tree
156
180
if searchStr == shared {
157
181
return false
158
182
}
183
+ //If the child's label is equal to the shared string, you have to
184
+ // traverse another level down the tree, so substring the search
185
+ // string, break the loop, and run it back
159
186
else if shared == e. label {
160
187
currEdge = e
161
188
var tempIndex = searchStr. startIndex
@@ -166,16 +193,18 @@ class RadixTree {
166
193
found = true
167
194
break
168
195
}
169
- //The child's label and the search string share a prefix
196
+ //If the child's label and the search string share a partial prefix,
197
+ // then both the label and the search string need to be substringed
198
+ // and a new branch needs to be created
170
199
else if shared. characters. count > 0 {
171
- //Cut the prefix off from both the search string and label
172
200
var labelIndex = e. label. characters. startIndex
173
201
//Create index objects and move them to after the shared prefix
174
202
for _ in 1 ... shared. characters. count {
175
203
index = index. successor ( )
176
204
labelIndex = labelIndex. successor ( )
177
205
}
178
- //Substring both the search string and the label from the shared prefix
206
+ //Substring both the search string and the label from the
207
+ // shared prefix
179
208
searchStr = searchStr. substringFromIndex ( index)
180
209
e. label = e. label. substringFromIndex ( labelIndex)
181
210
//Create 2 new edges and update parent/children values
@@ -195,10 +224,10 @@ class RadixTree {
195
224
e. children. append ( newEdge2)
196
225
return true
197
226
}
198
- //They don't share a prefix ( go to next child)
227
+ //If they don't share a prefix, go to next child
199
228
}
229
+ //If none of the children share a prefix, you have to create a new child
200
230
if ( !found) {
201
- //No children share a prefix, so create a new child
202
231
let newEdge = Edge ( searchStr)
203
232
currEdge. children. append ( newEdge)
204
233
newEdge. parent = currEdge
@@ -207,6 +236,7 @@ class RadixTree {
207
236
}
208
237
}
209
238
239
+ //Tells you if a string is in the tree
210
240
func find( _ str: String ) -> Bool {
211
241
//A radix tree always contains the empty string
212
242
if str == " " {
@@ -216,6 +246,7 @@ class RadixTree {
216
246
else if root. children. count == 0 {
217
247
return false
218
248
}
249
+ //searchStr and currEdge have the same functionality as insert()
219
250
var searchStr = str
220
251
var currEdge = root
221
252
while ( true ) {
0 commit comments