From 442b7e77d07fd3bad4e8b141c94593c75416374c Mon Sep 17 00:00:00 2001 From: Bhaskar Sawant Date: Sun, 2 Apr 2023 20:17:27 +0530 Subject: [PATCH 1/4] Added TopologicalSort implementaion on graph. --- Data-Structures/Graph/Graph.js | 59 ++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/Data-Structures/Graph/Graph.js b/Data-Structures/Graph/Graph.js index 1d8e941a11..85cacbec9e 100644 --- a/Data-Structures/Graph/Graph.js +++ b/Data-Structures/Graph/Graph.js @@ -1,24 +1,26 @@ class Graph { constructor () { this.adjacencyMap = {} + this.numberOfVertex = 0 } - addVertex (vertex) { + addVertex(vertex) { this.adjacencyMap[vertex] = [] + this.numberOfVertex++ } - containsVertex (vertex) { - return typeof (this.adjacencyMap[vertex]) !== 'undefined' + containsVertex(vertex) { + return typeof this.adjacencyMap[vertex] !== 'undefined' } - addEdge (vertex1, vertex2) { + addEdge(vertex1, vertex2) { if (this.containsVertex(vertex1) && this.containsVertex(vertex2)) { this.adjacencyMap[vertex1].push(vertex2) this.adjacencyMap[vertex2].push(vertex1) } } - printGraph (output = value => console.log(value)) { + printGraph(output = (value) => console.log(value)) { const keys = Object.keys(this.adjacencyMap) for (const i of keys) { const values = this.adjacencyMap[i] @@ -34,13 +36,14 @@ class Graph { * Prints the Breadth first traversal of the graph from source. * @param {number} source The source vertex to start BFS. */ - bfs (source, output = value => console.log(value)) { + bfs(source, output = (value) => console.log(value)) { const queue = [[source, 0]] // level of source is 0 const visited = new Set() while (queue.length) { const [node, level] = queue.shift() // remove the front of the queue - if (visited.has(node)) { // visited + if (visited.has(node)) { + // visited continue } @@ -56,8 +59,9 @@ class Graph { * Prints the Depth first traversal of the graph from source. * @param {number} source The source vertex to start DFS. */ - dfs (source, visited = new Set(), output = value => console.log(value)) { - if (visited.has(source)) { // visited + dfs(source, visited = new Set(), output = (value) => console.log(value)) { + if (visited.has(source)) { + // visited return } @@ -67,6 +71,40 @@ class Graph { this.dfs(neighbour, visited, output) } } + + _topologicalSort(v, visited, stack) { + // Mark the current node as visited. + visited[v] = true + + // Recur for all the vertices adjacent to thisvertex + for (let i of this.adjacencyMap[v]) { + if (!visited[i]) { + this._topologicalSort(i, visited, stack) + } + } + + // Push current vertex to stack which stores result + stack.push(v) + } + + // The function to do Topological Sort. It uses recursive _topologicalSort() + topologicalSort () { + const stack = [] + + // Mark all the vertices as not visited + const visited = new Array(this.numberOfVertex) + visited.fill(false) + + // Call the recursive helper function to store Topological Sort starting from all vertices one by one + for (let i = 0; i < visited.length; i++) { + if (visited[i] === false) { + this._topologicalSort(i + 1, visited, stack) + } + } + + // Return stack in reverse order + return stack.reverse() + } } const example = () => { @@ -96,6 +134,9 @@ const example = () => { // Depth first search at node 1 g.dfs(1) + + // Prints Topological sort of given graph + g.topologicalSort() } export { Graph, example } From c5463fcb25e6a57f1615621c999d17712977b9f4 Mon Sep 17 00:00:00 2001 From: Bhaskar Sawant Date: Sun, 2 Apr 2023 20:27:28 +0530 Subject: [PATCH 2/4] Corrected NPM style errors. --- Data-Structures/Graph/Graph.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Data-Structures/Graph/Graph.js b/Data-Structures/Graph/Graph.js index 85cacbec9e..34d2a8e41f 100644 --- a/Data-Structures/Graph/Graph.js +++ b/Data-Structures/Graph/Graph.js @@ -4,23 +4,23 @@ class Graph { this.numberOfVertex = 0 } - addVertex(vertex) { + addVertex (vertex) { this.adjacencyMap[vertex] = [] this.numberOfVertex++ } - containsVertex(vertex) { + containsVertex (vertex) { return typeof this.adjacencyMap[vertex] !== 'undefined' } - addEdge(vertex1, vertex2) { + addEdge (vertex1, vertex2) { if (this.containsVertex(vertex1) && this.containsVertex(vertex2)) { this.adjacencyMap[vertex1].push(vertex2) this.adjacencyMap[vertex2].push(vertex1) } } - printGraph(output = (value) => console.log(value)) { + printGraph (output = (value) => console.log(value)) { const keys = Object.keys(this.adjacencyMap) for (const i of keys) { const values = this.adjacencyMap[i] @@ -36,7 +36,7 @@ class Graph { * Prints the Breadth first traversal of the graph from source. * @param {number} source The source vertex to start BFS. */ - bfs(source, output = (value) => console.log(value)) { + bfs (source, output = (value) => console.log(value)) { const queue = [[source, 0]] // level of source is 0 const visited = new Set() @@ -59,7 +59,7 @@ class Graph { * Prints the Depth first traversal of the graph from source. * @param {number} source The source vertex to start DFS. */ - dfs(source, visited = new Set(), output = (value) => console.log(value)) { + dfs (source, visited = new Set(), output = (value) => console.log(value)) { if (visited.has(source)) { // visited return @@ -72,12 +72,12 @@ class Graph { } } - _topologicalSort(v, visited, stack) { + _topologicalSort (v, visited, stack) { // Mark the current node as visited. visited[v] = true // Recur for all the vertices adjacent to thisvertex - for (let i of this.adjacencyMap[v]) { + for (const i of this.adjacencyMap[v]) { if (!visited[i]) { this._topologicalSort(i, visited, stack) } From c438a8d024efdcf0ff516e1aa433c61c35cdd723 Mon Sep 17 00:00:00 2001 From: Bhaskar Sawant Date: Sun, 2 Apr 2023 21:26:13 +0530 Subject: [PATCH 3/4] Added jest test, Renamed var v to neighbor. --- Data-Structures/Graph/Graph.js | 26 ++++++++++++------------ Data-Structures/Graph/test/Graph.test.js | 23 +++++++++++++++++++++ 2 files changed, 36 insertions(+), 13 deletions(-) create mode 100644 Data-Structures/Graph/test/Graph.test.js diff --git a/Data-Structures/Graph/Graph.js b/Data-Structures/Graph/Graph.js index 34d2a8e41f..f811d6e815 100644 --- a/Data-Structures/Graph/Graph.js +++ b/Data-Structures/Graph/Graph.js @@ -1,26 +1,26 @@ class Graph { - constructor () { + constructor() { this.adjacencyMap = {} this.numberOfVertex = 0 } - addVertex (vertex) { + addVertex(vertex) { this.adjacencyMap[vertex] = [] this.numberOfVertex++ } - containsVertex (vertex) { - return typeof this.adjacencyMap[vertex] !== 'undefined' + containsVertex(vertex) { + return typeof this.adjacencyMap[vertex] !== undefined } - addEdge (vertex1, vertex2) { + addEdge(vertex1, vertex2) { if (this.containsVertex(vertex1) && this.containsVertex(vertex2)) { this.adjacencyMap[vertex1].push(vertex2) this.adjacencyMap[vertex2].push(vertex1) } } - printGraph (output = (value) => console.log(value)) { + printGraph(output = (value) => console.log(value)) { const keys = Object.keys(this.adjacencyMap) for (const i of keys) { const values = this.adjacencyMap[i] @@ -36,7 +36,7 @@ class Graph { * Prints the Breadth first traversal of the graph from source. * @param {number} source The source vertex to start BFS. */ - bfs (source, output = (value) => console.log(value)) { + bfs(source, output = (value) => console.log(value)) { const queue = [[source, 0]] // level of source is 0 const visited = new Set() @@ -59,7 +59,7 @@ class Graph { * Prints the Depth first traversal of the graph from source. * @param {number} source The source vertex to start DFS. */ - dfs (source, visited = new Set(), output = (value) => console.log(value)) { + dfs(source, visited = new Set(), output = (value) => console.log(value)) { if (visited.has(source)) { // visited return @@ -72,23 +72,23 @@ class Graph { } } - _topologicalSort (v, visited, stack) { + _topologicalSort(neighbor, visited, stack) { // Mark the current node as visited. - visited[v] = true + visited[neighbor] = true // Recur for all the vertices adjacent to thisvertex - for (const i of this.adjacencyMap[v]) { + for (const i of this.adjacencyMap[neighbor]) { if (!visited[i]) { this._topologicalSort(i, visited, stack) } } // Push current vertex to stack which stores result - stack.push(v) + stack.push(neighbor) } // The function to do Topological Sort. It uses recursive _topologicalSort() - topologicalSort () { + topologicalSort() { const stack = [] // Mark all the vertices as not visited diff --git a/Data-Structures/Graph/test/Graph.test.js b/Data-Structures/Graph/test/Graph.test.js new file mode 100644 index 0000000000..1ca43f9056 --- /dev/null +++ b/Data-Structures/Graph/test/Graph.test.js @@ -0,0 +1,23 @@ +import { Graph } from '../Graph' + +describe('Test Graph', () => { + const vertices = [1, 2, 3, 4, 5] + const graph = new Graph() + + // adding vertices + for (let i = 0; i < vertices.length; i++) { + graph.addVertex(vertices[i]) + } + + // adding edges + graph.addEdge(1, 2) + graph.addEdge(1, 3) + graph.addEdge(2, 4) + graph.addEdge(2, 5) + + //testing Topological Sort + it('topological sort', () => { + expect(graph.topologicalSort()).toEqual([1, 3, 2, 5, 4]) + }) + +}) From 80fa5692fb009e63e1401982366a019f56ab17c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=BCller?= <34514239+appgurueu@users.noreply.github.com> Date: Sun, 2 Apr 2023 19:14:44 +0200 Subject: [PATCH 4/4] Improve test --- Data-Structures/Graph/test/Graph.test.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Data-Structures/Graph/test/Graph.test.js b/Data-Structures/Graph/test/Graph.test.js index 1ca43f9056..025e14785f 100644 --- a/Data-Structures/Graph/test/Graph.test.js +++ b/Data-Structures/Graph/test/Graph.test.js @@ -1,23 +1,25 @@ import { Graph } from '../Graph' -describe('Test Graph', () => { - const vertices = [1, 2, 3, 4, 5] +describe('Graph', () => { const graph = new Graph() - // adding vertices - for (let i = 0; i < vertices.length; i++) { - graph.addVertex(vertices[i]) + for (let v = 1; v <= 5; v++) { + graph.addVertex(v) } - // adding edges graph.addEdge(1, 2) graph.addEdge(1, 3) graph.addEdge(2, 4) graph.addEdge(2, 5) - //testing Topological Sort - it('topological sort', () => { - expect(graph.topologicalSort()).toEqual([1, 3, 2, 5, 4]) + it('returns any valid topological sort', () => { + expect([ + [1, 2, 3, 4, 5], + [1, 3, 2, 4, 5], + [1, 3, 2, 5, 4], + [1, 2, 4, 3, 5], + [1, 2, 5, 3, 4], + [1, 2, 4, 5, 3], + ]).toContain(graph.topologicalSort()) }) - })