-
Notifications
You must be signed in to change notification settings - Fork 108
/
Graph.kt
106 lines (91 loc) · 2.98 KB
/
Graph.kt
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
package structures
import java.util.LinkedList
import kotlin.collections.LinkedHashSet
/**
*
* Graph is a non-linear data structure consisting of vertices and edges.
*
* The vertices are sometimes also referred to as nodes and the edges are lines or arcs that connect any two nodes in the graph.
*
* More formally a Graph is composed of a set of vertices V and a set of edges E. The graph is denoted by G(E, V).
*
* Undirected graph is a type of graph where the edges have no specified direction assigned to the them.
*
*/
class Graph<T> {
private val data = linkedMapOf<Vertex<T>, MutableList<Vertex<T>>>()
// Complexity: O(1)
fun addVertex(value: T) {
data.putIfAbsent(Vertex(value), mutableListOf())
}
// Complexity: O(n)
fun removeVertex(value: T) {
val removingVertex = Vertex(value)
data.values.forEach { list ->
list.remove(removingVertex)
}
data.remove(removingVertex)
}
// Complexity: O(1)
fun addEdge(value1: T, value2: T) {
val vertex1 = Vertex(value1)
val vertex2 = Vertex(value2)
data[vertex1]?.add(vertex2)
data[vertex2]?.add(vertex1)
}
// Complexity: O(1)
fun removeEdge(value1: T, value2: T) {
val vertex1 = Vertex(value1)
val vertex2 = Vertex(value2)
data[vertex1]?.remove(vertex2)
data[vertex2]?.remove(vertex1)
}
// returns the associated vertices with the given vertex value
fun connectedVertexes(value: T) = data[Vertex(value)]?.map { it.value } ?: emptyList()
/**
*
* Traversal of the graph in depth,
*
* returns all vertices of the graph
*
*/
fun depthFirstTraversal() : List<T> {
val firstVertex = data.keys.firstOrNull() ?: return emptyList()
val visited = LinkedHashSet<T>()
val queue = LinkedList<Vertex<T>>()
queue.push(firstVertex)
while (queue.isNotEmpty()) {
val vertex = queue.pollFirst()
if (!visited.contains(vertex.value)) {
visited.add(vertex.value)
queue.addAll(data[vertex] ?: emptyList())
}
}
return visited.toList()
}
/**
*
* Traversal of the graph in breadth,
*
* returns all vertices of the graph
*
*/
fun breadthFirstTraversal() : List<T> {
val firstVertex = data.keys.firstOrNull() ?: return emptyList()
val visited = LinkedHashSet<T>()
val queue = LinkedList<Vertex<T>>()
queue.add(firstVertex)
visited.add(firstVertex.value)
while (queue.isNotEmpty()) {
val vertex = queue.pollFirst()
data[vertex]?.forEach { connectedVertex ->
if (!visited.contains(connectedVertex.value)) {
visited.add(connectedVertex.value)
queue.add(connectedVertex)
}
}
}
return visited.toList()
}
private data class Vertex<T>(val value: T)
}