1
1
import Foundation
2
2
3
+ class Root {
3
4
4
- public class RadixNode {
5
- public var parent : RadixNode ?
6
- public var children = [ ( childNode: RadixNode, childEdgeLabel: String) ] ( )
5
+ var children : [ Edge ]
7
6
8
- public init ( ) {
9
-
10
- }
11
-
12
- public init ( value: String ) {
13
- self . children. append ( ( childNode: RadixNode ( ) , childEdgeLabel: value) )
14
- }
15
-
16
- public func addChild( _ node: RadixNode , _ label: String ) {
17
- children. append ( ( node, label) )
18
- node. parent = self
19
- }
20
-
21
- public func getChildren( ) -> [ ( childNode: RadixNode , childEdgeLabel: String ) ] {
22
- return children
7
+ init ( ) {
8
+ children = [ Edge] ( )
23
9
}
24
10
25
- public func getChildAt( i: Int ) -> ( RadixNode , String ) ? {
26
- if i >= children. count {
27
- return nil
11
+ func height( ) -> Int {
12
+ if children. count == 0 {
13
+ return 1
14
+ }
15
+ else {
16
+ var max = 1
17
+ for c in children {
18
+ if c. height ( ) > max {
19
+ max = c. height ( )
20
+ }
21
+ }
22
+ return 1 + max
28
23
}
29
- return children [ i]
30
24
}
31
25
32
- public func getParent ( ) -> RadixNode ? {
33
- return parent
26
+ func level ( ) -> Int {
27
+ return 0
34
28
}
35
29
36
- public func isLeaf( ) -> Bool {
37
- return children. count == 0
30
+ func printRoot( ) {
31
+ //print("children: \(children.count)")
32
+ //print("split at: \(children.count/2-1)")
33
+ if ( children. count > 1 ) {
34
+ for c in 0 ... children. count/ 2 - 1 {
35
+ children [ c] . printEdge ( )
36
+ print ( " | " )
37
+ }
38
+ }
39
+ else if children. count > 0 {
40
+ children [ 0 ] . printEdge ( )
41
+ }
42
+ print ( " ROOT " )
43
+ //print("second half starts at: \(children.count/2)")
44
+ if children. count > 1 {
45
+ for c in children. count/ 2 ... children. count- 1 {
46
+ children [ c] . printEdge ( )
47
+ print ( " | " )
48
+ }
49
+ }
50
+ print ( )
38
51
}
39
52
}
40
53
41
- public class RadixTree {
42
- public var root : RadixNode
54
+ class Edge : Root {
43
55
44
- //Construct an "empty" RadixTree with a single node
45
- public init ( ) {
46
- root = RadixNode ( )
47
- }
56
+ var parent : Root ?
57
+ var label : String
48
58
49
- public init ( value: String ) {
50
- self . root = RadixNode ( value: value)
59
+ init ( _ label: String ) { //Edge(label: "label")
60
+ self . label = label
61
+ super. init ( )
51
62
}
52
63
53
- public func find( str: String , node: RadixNode ? ) -> Bool {
54
- var currNode : RadixNode
55
- var search = str
56
- if ( node == nil ) {
57
- currNode = self . root
64
+ override
65
+ func level( ) -> Int {
66
+ if parent != nil {
67
+ return 1 + parent!. level ( )
58
68
}
59
69
else {
60
- currNode = node!
61
- }
62
- if ( str == " " ) {
63
- return true
64
- }
65
- else {
66
- for n in 0 ... currNode. children. count- 1 {
67
- if ( str. hasPrefix ( currNode. children [ n] . childEdgeLabel) ) {
68
- let elementsFound = currNode. children [ n] . childEdgeLabel. characters. count
69
- search = search. substringFromIndex ( search. startIndex. advanced ( by: elementsFound) )
70
- currNode = currNode. children [ n] . childNode
71
- find ( str: search, node: currNode)
72
- }
73
- }
70
+ return 1
74
71
}
75
- return false
76
72
}
77
73
78
- public func insert ( str : String , node : RadixNode ? ) -> Bool {
79
- var search = str
80
- var currNode : RadixNode
81
- if ( node == nil ) {
82
- currNode = self . root
74
+ func printEdge ( ) {
75
+ if children . count > 1 {
76
+ for c in 0 ... children . count / 2 - 1 {
77
+ children [ c ] . printEdge ( )
78
+ }
83
79
}
84
- else {
85
- currNode = node!
80
+ else if children. count > 0 {
81
+ children [ 0 ] . printEdge ( )
82
+ }
83
+ for x in 1 ... level ( ) {
84
+ if x == level ( ) {
85
+ print ( " |------> " , terminator: " " )
86
+ }
87
+ else if x == 1 {
88
+ print ( " | " , terminator: " " )
89
+ }
90
+ else if x == level ( ) - 1 {
91
+ print ( " | " , terminator: " " )
92
+ }
93
+ else {
94
+ print ( " | " , terminator: " " )
95
+ }
86
96
}
87
- //Case 0: str == "" (it is already in the tree)
88
- // -> return false
89
- if ( str == " " ) {
90
- return false
97
+ print ( label)
98
+ if children. count == 0 {
99
+ for _ in 1 ... level ( ) {
100
+ print ( " | " , terminator: " " )
101
+ }
102
+ print ( )
91
103
}
92
- else {
93
- for c in currNode. children {
94
-
95
- //Temp is the string of the prefix that the label and the
96
- // search string have in common.
97
- //let temp = currNode.children[c].childEdgeLabel.sharePrefix(str)
98
-
99
- //Case 3: currNode has a child that shares some prefix with str
100
- // -> little bit more complicated
101
- //if temp == 0 {
104
+ if children. count > 1 {
105
+ for c in children. count/ 2 ... children. count- 1 {
106
+ children [ c] . printEdge ( )
107
+ }
108
+ }
109
+ }
110
+ }
102
111
103
- //Remove the shared characters from both the search string and
104
- // label
105
- //currNode.children[c].childEdgeLabel.substringFromIndex(temp.count)
106
- //str.substringFromIndex(temp.count)
112
+ class RadixTree {
107
113
114
+ var root : Root
108
115
109
- //}
110
-
116
+ init ( ) {
117
+ root = Root ( )
118
+ }
111
119
112
- //Case 1: currNode has no children that share a prefix with str
113
- // -> create a new child for currNode
120
+ func height( ) -> Int {
121
+ return root. height ( ) - 1
122
+ }
114
123
124
+ func insert( _ str: String ) -> Bool {
125
+ //Account for a blank input
126
+ if str == " " {
127
+ return true
128
+ }
129
+ //Account for an empty tree
130
+ if root. children. count == 0 {
131
+ root. children. append ( Edge ( str) )
132
+ return true
133
+ }
134
+ var searchStr = str
135
+ var currEdge = root
136
+ while ( true ) {
137
+ var found = false
138
+ var i = 0
139
+ if currEdge. children. count == 0 {
140
+ let newEdge = Edge ( searchStr)
141
+ currEdge. children. append ( newEdge)
142
+ newEdge. parent = currEdge
143
+ }
144
+ for e in currEdge. children {
145
+ //Get the shared
146
+ var shared = sharedPrefix ( searchStr, e. label)
147
+ var index = shared. startIndex
148
+ //The search string is equal to the shared string
149
+ //so the string already exists in the tree
150
+ if searchStr == shared {
151
+ return false
152
+ }
153
+ else if shared == e. label {
154
+ currEdge = e
155
+ var tempIndex = searchStr. startIndex
156
+ for _ in 1 ... shared. characters. count {
157
+ tempIndex = tempIndex. successor ( )
158
+ }
159
+ searchStr = searchStr. substringFromIndex ( tempIndex)
160
+ found = true
161
+ break
162
+ }
163
+ //The child's label and the search string share a prefix
164
+ else if shared. characters. count > 0 {
165
+ //Cut the prefix off from both the search string and label
166
+ var labelIndex = e. label. characters. startIndex
167
+ //Create index objects and move them to after the shared prefix
168
+ for _ in 1 ... shared. characters. count {
169
+ index = index. successor ( )
170
+ labelIndex = labelIndex. successor ( )
171
+ }
172
+ //Substring both the search string and the label from the shared prefix
173
+ searchStr = searchStr. substringFromIndex ( index)
174
+ e. label = e. label. substringFromIndex ( labelIndex)
175
+ //Create 2 new edges and update parent/children values
176
+ let newEdge = Edge ( e. label)
177
+ e. label = shared
178
+ for ec in e. children {
179
+ newEdge. children. append ( ec)
180
+ }
181
+ newEdge. parent = e
182
+ e. children. removeAll ( )
183
+ for nec in newEdge. children {
184
+ nec. parent = newEdge
185
+ }
186
+ e. children. append ( newEdge)
187
+ let newEdge2 = Edge ( searchStr)
188
+ newEdge2. parent = e
189
+ e. children. append ( newEdge2)
190
+ return true
191
+ }
192
+ //They don't share a prefix (go to next child)
193
+ i += 1
194
+ }
195
+ if ( !found) {
196
+ //No children share a prefix, so create a new child
197
+ let newEdge = Edge ( searchStr)
198
+ currEdge. children. append ( newEdge)
199
+ newEdge. parent = currEdge
200
+ return true
201
+ }
202
+ }
203
+ }
115
204
116
- //Case 2: currNode has a child whose label is a prefix of str
117
- // -> recurse down
205
+ func printTree( ) {
206
+ root. printRoot ( )
207
+ }
208
+ }
118
209
119
- }
210
+ //Returns the prefix that is shared between the two input strings
211
+ //i.e. sharedPrefix("court", "coral") -> "co"
212
+ func sharedPrefix( _ str1: String , _ str2: String ) -> String {
213
+ var temp = " "
214
+ var c1 = str1. characters. startIndex
215
+ var c2 = str2. characters. startIndex
216
+ for _ in 0 ... min ( str1. characters. count- 1 , str2. characters. count- 1 ) {
217
+ if str1 [ c1] == str2 [ c2] {
218
+ temp. append ( str1 [ c1] )
219
+ c1 = c1. successor ( )
220
+ c2 = c2. successor ( )
221
+ }
222
+ else {
223
+ return temp
120
224
}
121
- return false
122
225
}
226
+ return temp
123
227
}
0 commit comments