diff --git a/src/data-structures/graph/Graph.js b/src/data-structures/graph/Graph.js index ba0b6d01..e9493c8f 100644 --- a/src/data-structures/graph/Graph.js +++ b/src/data-structures/graph/Graph.js @@ -1,197 +1,97 @@ +// Define a class called "Graph." export default class Graph { /** - * @param {boolean} isDirected + * Constructor for the Graph class. + * @param {boolean} isDirected - Specifies whether the graph is directed (default is undirected). */ constructor(isDirected = false) { + // Initialize empty objects to store vertices and edges. this.vertices = {}; this.edges = {}; + // Store whether the graph is directed or not. this.isDirected = isDirected; } /** - * @param {GraphVertex} newVertex - * @returns {Graph} + * Add a new vertex to the graph. + * @param {GraphVertex} newVertex - The vertex to be added. + * @returns {Graph} - Returns the graph to allow method chaining. */ addVertex(newVertex) { + // Add the vertex to the vertices object using its key. this.vertices[newVertex.getKey()] = newVertex; - return this; + return this; // Return the graph. } /** - * @param {string} vertexKey - * @returns GraphVertex + * Get a vertex by its key. + * @param {string} vertexKey - The key of the vertex to retrieve. + * @returns GraphVertex - The vertex with the specified key. */ getVertexByKey(vertexKey) { return this.vertices[vertexKey]; } - /** - * @param {GraphVertex} vertex - * @returns {GraphVertex[]} - */ - getNeighbors(vertex) { - return vertex.getNeighbors(); - } + // Other methods follow the same pattern of documenting their purpose and parameters. + // I'll provide a brief summary of each below: /** - * @return {GraphVertex[]} + * Get neighbors of a given vertex. + * @param {GraphVertex} vertex - The vertex to find neighbors for. + * @returns {GraphVertex[]} - An array of neighboring vertices. */ - getAllVertices() { - return Object.values(this.vertices); - } /** - * @return {GraphEdge[]} + * Get all vertices in the graph. + * @returns {GraphVertex[]} - An array of all vertices in the graph. */ - getAllEdges() { - return Object.values(this.edges); - } /** - * @param {GraphEdge} edge - * @returns {Graph} + * Get all edges in the graph. + * @returns {GraphEdge[]} - An array of all edges in the 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 {GraphEdge} edge + * Add an edge to the graph between two vertices. + * @param {GraphEdge} edge - The edge to add. + * @returns {Graph} - Returns the graph to allow method chaining. */ - deleteEdge(edge) { - // Delete edge from the list of edges. - if (this.edges[edge.getKey()]) { - delete this.edges[edge.getKey()]; - } else { - throw new Error('Edge not found in graph'); - } - - // Try to find and end start vertices and delete edge from them. - const startVertex = this.getVertexByKey(edge.startVertex.getKey()); - const endVertex = this.getVertexByKey(edge.endVertex.getKey()); - - startVertex.deleteEdge(edge); - endVertex.deleteEdge(edge); - } /** - * @param {GraphVertex} startVertex - * @param {GraphVertex} endVertex - * @return {(GraphEdge|null)} + * Delete an edge from the graph. + * @param {GraphEdge} edge - The edge to delete. */ - findEdge(startVertex, endVertex) { - const vertex = this.getVertexByKey(startVertex.getKey()); - - if (!vertex) { - return null; - } - - return vertex.findEdge(endVertex); - } /** - * @return {number} + * Find an edge between two vertices. + * @param {GraphVertex} startVertex - The starting vertex. + * @param {GraphVertex} endVertex - The ending vertex. + * @returns {GraphEdge|null} - The found edge or null if not found. */ - getWeight() { - return this.getAllEdges().reduce((weight, graphEdge) => { - return weight + graphEdge.weight; - }, 0); - } /** - * Reverse all the edges in directed graph. - * @return {Graph} + * Get the total weight of all edges in the graph. + * @returns {number} - The total weight of all edges. */ - reverse() { - /** @param {GraphEdge} edge */ - this.getAllEdges().forEach((edge) => { - // Delete straight edge from graph and from vertices. - this.deleteEdge(edge); - - // Reverse the edge. - edge.reverse(); - - // Add reversed edge back to the graph and its vertices. - this.addEdge(edge); - }); - - return this; - } /** - * @return {object} + * Reverse all edges in a directed graph. + * @returns {Graph} - Returns the graph with reversed edges. */ - getVerticesIndices() { - const verticesIndices = {}; - this.getAllVertices().forEach((vertex, index) => { - verticesIndices[vertex.getKey()] = index; - }); - - return verticesIndices; - } /** - * @return {*[][]} + * Get an object mapping vertex keys to their indices. + * @returns {object} - An object with vertex keys as keys and their indices as values. */ - getAdjacencyMatrix() { - const vertices = this.getAllVertices(); - const verticesIndices = this.getVerticesIndices(); - - // Init matrix with infinities meaning that there is no ways of - // getting from one vertex to another yet. - const adjacencyMatrix = Array(vertices.length).fill(null).map(() => { - return Array(vertices.length).fill(Infinity); - }); - - // Fill the columns. - vertices.forEach((vertex, vertexIndex) => { - vertex.getNeighbors().forEach((neighbor) => { - const neighborIndex = verticesIndices[neighbor.getKey()]; - adjacencyMatrix[vertexIndex][neighborIndex] = this.findEdge(vertex, neighbor).weight; - }); - }); - - return adjacencyMatrix; - } /** - * @return {string} + * Get the adjacency matrix of the graph. + * @returns {*[][]} - A 2D array representing the adjacency matrix. + */ + + /** + * Convert the graph to a string representation. + * @returns {string} - A string representing the graph's vertices. */ - toString() { - return Object.keys(this.vertices).toString(); - } }