-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGraphStructure.kt
More file actions
200 lines (179 loc) · 4.87 KB
/
GraphStructure.kt
File metadata and controls
200 lines (179 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
package dataStructures.graph
/**
* Implementation of a non-oriented Graph
*/
class GraphStructure<I, D> : Graph<I, D> {
/**
* Vertex on the graph
* @property data Data of a given Vertex
* @property id Identifier of a Graph
* @property edges Set of edges (aka) reference of links between Vertexes
*/
data class Vertex<I, D>(override val id: I, override var data: D) : Graph.Vertex<I, D> {
private val edges = mutableSetOf<Graph.Edge<I>?>()
/**
* Function that returns a set of every adjacent Edges of
* a certain Vertex
*
* @return A set of edges might be an empty set if there
* are no Edges attached to the Vertex
*/
override fun getAdjacencies(): MutableSet<Graph.Edge<I>?> {
return edges
}
/**
* Replaces the data of a given Vertex
*
* @param newData New data to store in the Vertex
* @return The new data
*/
override fun setData(newData: D): D {
data = newData
return newData
}
}
/**
* Class that implements an Edge of the Graph
*
* @property id Identifier of the origin Vertex
* @property adjacent Identifier of the destiny Vertex
*/
data class Edge<I>(override val id: I, override val adjacent: I) : Graph.Edge<I>
val map = HashMap<I, Graph.Vertex<I, D>>()
override val size: Int
get() {
return map.size
}
/**
* Adds a vertex to the Graph if the given Vertex is
* already in the graph, returns null without adding it
*
* @param id ID of the Vertex to add
* @param d Data of the Vertex to add
* @return The data of the new vertex or null if
* the vertex was already in the graph
*/
override fun addVertex(id: I, d: D): D? {
val vertex = getVertex(id)
if (vertex != null) return null
map[id] = Vertex(id, d)
return d
}
/**
* Adds a new Edge to the Graph, identifying the origin
* and destiny vertices.
* If the origin Vertex does not exist, returns null without
* adding it
*
* @param id ID of the origin Vertex
* @param idAdj ID of the destiny Vertex
* @return The ID of the adjacent vertex or null if it doesn't exist
*/
override fun addEdge(id: I, idAdj: I): I? {
val address = getVertex(id) ?: return null
address.getAdjacencies().add(Edge(id, idAdj))
return idAdj
}
/**
* Gets a Vertex given its ID
*
* @param id ID of the Vertex to search
* @return A Vertex or null if it doesn't exist in the graph
*/
override fun getVertex(id: I): Graph.Vertex<I, D>? {
return map[id]
}
/**
* Gets an Edge given its origin and destiny Vertices
*
* @param id ID of the origin Vertex
* @param idAdj ID of the destiny Vertex
* @return An Edge or null if it doesn't exist in the graph
*/
override fun getEdge(id: I, idAdj: I): Graph.Edge<I>? {
val address = getVertex(id) ?: return null
address.getAdjacencies().forEach {
if (it!!.adjacent == idAdj) return it
}
return null
}
/**
* Iterates over the existing Vertices
*
* @return Returns an Iterable object that allows to iterate over
* the existing Vertices
*/
override fun iterator(): Iterator<Graph.Vertex<I, D>> {
return object : Iterator<Graph.Vertex<I, D>> {
val iterator = map.iterator()
/**
* Verifies if the next vertex is different from null
*
* @return True if there is more vertex and false if there
* aren't
*/
override fun hasNext(): Boolean {
return iterator.hasNext()
}
/**
* Iterates in the map if the next vertex is different from
* null
*
* @return Next vertex or trows exception
*/
override fun next(): Graph.Vertex<I, D> {
if (!hasNext()) throw NoSuchElementException("No such Vertex")
return iterator.next().value
}
}
}
/**
* Makes the Set of Edges iterable
*
* @return Returns an Iterable object that allows to iterate over
* the Edges
*/
override fun edgesIterator(): Iterator<Graph.Edge<I>> {
return object : Iterator<Graph.Edge<I>> {
val vertexIterator = map.iterator()
var edgeIterator: MutableIterator<Graph.Edge<I>?>? = null
var currentEdge: Graph.Edge<I>? = null
/**
* Verifies if the next edge is different from null
*
* @return True if there are more edges and false if
* there aren't
*/
override fun hasNext(): Boolean {
if (currentEdge != null)
return true
if (vertexIterator.hasNext()) {
if (edgeIterator == null) {
edgeIterator = vertexIterator.next().value.getAdjacencies().iterator()
hasNext()
} else {
if (edgeIterator!!.hasNext()) {
currentEdge = edgeIterator!!.next()
return true
} else {
edgeIterator = null
hasNext()
}
}
}
return false
}
/**
* Iterates in the map if the next edge is different from null
*
* @return Next-edge or trows exception
*/
override fun next(): Graph.Edge<I> {
if (!hasNext()) throw NoSuchElementException("No such edge")
val aux = edgeIterator
edgeIterator = null
return aux!!.next()!!
}
}
}
}