mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2025-12-08 19:06:00 +00:00
129 lines
2.7 KiB
JavaScript
129 lines
2.7 KiB
JavaScript
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;
|
|
}
|
|
|
|
/**
|
|
* @return {number}
|
|
*/
|
|
getWeight() {
|
|
return this.getAllEdges().reduce((weight, graphEdge) => {
|
|
return weight + graphEdge.weight;
|
|
}, 0);
|
|
}
|
|
|
|
/**
|
|
* @return {string}
|
|
*/
|
|
toString() {
|
|
return Object.keys(this.vertices).toString();
|
|
}
|
|
}
|