Skip to content

Commit cf7c087

Browse files
committed
Updated RadixTree.swift and main.swift
1 parent 32c558b commit cf7c087

File tree

2 files changed

+208
-102
lines changed

2 files changed

+208
-102
lines changed

Radix-Tree/RadixTree.swift

Lines changed: 191 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,227 @@
11
import Foundation
22

3+
class Root {
34

4-
public class RadixNode {
5-
public var parent: RadixNode?
6-
public var children = [(childNode: RadixNode, childEdgeLabel: String)]()
5+
var children: [Edge]
76

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]()
239
}
2410

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
2823
}
29-
return children[i]
3024
}
3125

32-
public func getParent() -> RadixNode? {
33-
return parent
26+
func level() -> Int {
27+
return 0
3428
}
3529

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()
3851
}
3952
}
4053

41-
public class RadixTree {
42-
public var root: RadixNode
54+
class Edge: Root {
4355

44-
//Construct an "empty" RadixTree with a single node
45-
public init() {
46-
root = RadixNode()
47-
}
56+
var parent: Root?
57+
var label: String
4858

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()
5162
}
5263

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()
5868
}
5969
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
7471
}
75-
return false
7672
}
7773

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+
}
8379
}
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+
}
8696
}
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()
91103
}
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+
}
102111

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 {
107113

114+
var root: Root
108115

109-
//}
110-
116+
init() {
117+
root = Root()
118+
}
111119

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+
}
114123

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+
}
115204

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+
}
118209

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
120224
}
121-
return false
122225
}
226+
return temp
123227
}

Radix-Tree/main.swift

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,24 +40,26 @@ radixWiki.insert("chime")
4040
radixWiki.insert("courting")
4141
radixWiki.insert("courted")
4242

43+
radixWiki.insert("rubicunduses")
44+
4345
print("PRINT TEST-------------------------------")
4446
radixWiki.printTree()
4547

46-
// let h = radix.height()
47-
// let h2 = radix2.height()
48-
// let hwiki = radixWiki.height()
49-
// print("Height of tree: \(h)")
50-
// print("height of second tree: \(h2)")
51-
// print("Height of wikipedia tree: \(hwiki)")
48+
let h = radix.height()
49+
let h2 = radix2.height()
50+
let hwiki = radixWiki.height()
51+
print("Height of tree: \(h)")
52+
print("height of second tree: \(h2)")
53+
print("Height of wikipedia tree: \(hwiki)")
5254

53-
// print(radixWiki.root.level())
54-
// print(radixWiki.root.children[0].level())
55-
// print(radixWiki.root.children[0].children[0].level())
56-
// print(radixWiki.root.children[0].children[0].children[0].level())
55+
print(radixWiki.root.level())
56+
print(radixWiki.root.children[0].level())
57+
print(radixWiki.root.children[0].children[0].level())
58+
print(radixWiki.root.children[0].children[0].children[0].level())
5759

58-
// print("\t\t\t\t\t\ttest")
59-
// print("PRINT TEST-------------------------------")
60-
// radixWiki.printTree()
60+
print("\t\t\t\t\t\ttest")
61+
print("PRINT TEST-------------------------------")
62+
radixWiki.printTree()
6163

62-
// print("PRINT TEST-------------------------------")
63-
// radix.printTree()
64+
print("PRINT TEST-------------------------------")
65+
radix.printTree()

0 commit comments

Comments
 (0)