export default class Graph { /** * @param {boolean} isDirected */ constructor(isDirected = false) { this.vertices = {}; 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(); } /** * @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()); } // @TODO: Check if edge has been already added. // 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 */ 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(); } }