forked from trekhleb/javascript-algorithms
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGraph.js
116 lines (100 loc) · 2.47 KB
/
Graph.js
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
export default class Graph {
/**
* @param {boolean} isDirected
*/
constructor(isDirected = false) {
this.vertices = {};
this.edges = {};
this.isDirected = isDirected;
}
/**
* @param {GraphVertex} newVertex
* @returns {Graph}
*/
addVertex(newVertex) {
this.vertices[newVertex.getKey()] = newVertex;
return this;
}
/**
* @param {string} vertexKey
* @returns GraphVertex
*/
getVertexByKey(vertexKey) {
return this.vertices[vertexKey];
}
/**
* @param {GraphVertex} vertex
*/
getNeighbors(vertex) {
return vertex.getNeighbors();
}
/**
* @return {GraphVertex[]}
*/
getAllVertices() {
return Object.values(this.vertices);
}
/**
* @return {GraphEdge[]}
*/
getAllEdges() {
return Object.values(this.edges);
}
/**
* @param {GraphEdge} edge
* @returns {Graph}
*/
addEdge(edge) {
// Try to find and end start vertices.
let startVertex = this.getVertexByKey(edge.startVertex.getKey());
let endVertex = this.getVertexByKey(edge.endVertex.getKey());
// Insert start vertex if it wasn't inserted.
if (!startVertex) {
this.addVertex(edge.startVertex);
startVertex = this.getVertexByKey(edge.startVertex.getKey());
}
// Insert end vertex if it wasn't inserted.
if (!endVertex) {
this.addVertex(edge.endVertex);
endVertex = this.getVertexByKey(edge.endVertex.getKey());
}
// Check if edge has been already added.
if (this.edges[edge.getKey()]) {
throw new Error('Edge has already been added before');
} else {
this.edges[edge.getKey()] = edge;
}
// Add edge to the vertices.
if (this.isDirected) {
// If graph IS directed then add the edge only to start vertex.
startVertex.addEdge(edge);
} else {
// If graph ISN'T directed then add the edge to both vertices.
startVertex.addEdge(edge);
endVertex.addEdge(edge);
}
return this;
}
/**
* @param {GraphVertex} startVertex
* @param {GraphVertex} endVertex
* @return {(GraphEdge|null)}
*/
findEdge(startVertex, endVertex) {
const vertex = this.getVertexByKey(startVertex.getKey());
return vertex.findEdge(endVertex);
}
/**
* @param {string} vertexKey
* @returns {GraphVertex}
*/
findVertexByKey(vertexKey) {
if (this.vertices[vertexKey]) {
return this.vertices[vertexKey];
}
return null;
}
toString() {
return Object.keys(this.vertices).toString();
}
}