From 5faae11e16e8456ba4739a2c8e6a113fc261a144 Mon Sep 17 00:00:00 2001 From: dongjji Date: Tue, 22 Mar 2022 19:55:54 +0900 Subject: [PATCH 1/3] Add Graph3 (add DFS in Iterative Way) --- Data-Structures/Graph/Graph3.js | 135 ++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 Data-Structures/Graph/Graph3.js diff --git a/Data-Structures/Graph/Graph3.js b/Data-Structures/Graph/Graph3.js new file mode 100644 index 0000000000..91fac6ad2d --- /dev/null +++ b/Data-Structures/Graph/Graph3.js @@ -0,0 +1,135 @@ +class Graph { + constructor() { + this.adjacencyObject = {} + } + + addVertex(vertex) { + if (!this.adjacencyObject[vertex]) this.adjacencyObject[vertex] = [] + } + + addEdge(vertex1, vertex2) { + if (this.adjacencyObject[vertex1] && this.adjacencyObject[vertex2]) { + this.adjacencyObject[vertex1].push(vertex2) + this.adjacencyObject[vertex2].push(vertex1) + } else { + return undefined + } + } + + removeEdge(vertex1, vertex2) { + if (this.adjacencyObject[vertex1] && this.adjacencyObject[vertex2]) { + this.adjacencyObject[vertex1] = this.adjacencyObject[vertex1].filter( + (v) => v !== vertex2 + ) + this.adjacencyObject[vertex2] = this.adjacencyObject[vertex2].filter( + (v) => v !== vertex1 + ) + } else { + return undefined + } + } + + removeVertex(vertex) { + if (this.adjacencyObject[vertex]) { + while (this.adjacencyObject[vertex].length) { + const adjacentVertex = this.adjacencyObject[vertex].pop() + this.removeEdge(vertex, adjacentVertex) + } + } else { + return undefined + } + } + + /** + * Return DFS(Depth First Search) List Using Recursive Method + */ + DFS(start) { + const result = [] + const visited = {} + const adjacencyObject = this.adjacencyObject + + function dfs(vertex) { + if (!vertex) return null + visited[vertex] = true + result.push(vertex) + adjacencyObject[vertex].forEach((neighbor) => { + if (!visited[neighbor]) { + dfs(neighbor) + } + }) + } + + dfs(start) + return result + } + + /** + * Return DFS(Depth First Search) List Using Iteration + */ + DFS_iterative(start) { + const stack = [start] + const visited = {} + visited[start] = true + + const result = [] + let currentVertex + + while (stack.length) { + currentVertex = stack.pop() + result.push(currentVertex) + + this.adjacencyObject[currentVertex].forEach((neighbor) => { + if (!visited[neighbor]) { + visited[neighbor] = true + stack.push(neighbor) + } + }) + } + return result + } + + BFS(start) { + const queue = [start] + const visited = {} + visited[start] = true + + let currentVertex + const result = [] + + while (queue.length) { + currentVertex = queue.shift() + result.push(currentVertex) + + this.adjacencyObject[currentVertex].forEach((neighbor) => { + if (!visited[neighbor]) { + visited[neighbor] = true + queue.push(neighbor) + } + }) + } + return result + } +} + +// example +// const g = new Graph() +// g.addVertex('A') +// g.addVertex('B') +// g.addVertex('C') +// g.addVertex('D') +// g.addVertex('E') +// g.addVertex('F') + +// g.addEdge('A', 'B') +// g.addEdge('A', 'C') +// g.addEdge('B', 'D') +// g.addEdge('C', 'E') +// g.addEdge('D', 'E') +// g.addEdge('D', 'F') +// g.addEdge('E', 'F') + +// g.removeVertex('B') + +// console.log(g.BFS('A')) + +export { Graph } From d2fb68750a2f5c1301240fe283e527c5190601a2 Mon Sep 17 00:00:00 2001 From: dongjji Date: Wed, 23 Mar 2022 01:54:43 +0900 Subject: [PATCH 2/3] Remove example code and add test code (Graph3) --- Data-Structures/Graph/Graph3.js | 47 +++++--------- Data-Structures/Graph/test/Graph3.test.js | 75 +++++++++++++++++++++++ 2 files changed, 91 insertions(+), 31 deletions(-) create mode 100644 Data-Structures/Graph/test/Graph3.test.js diff --git a/Data-Structures/Graph/Graph3.js b/Data-Structures/Graph/Graph3.js index 91fac6ad2d..eed4b60cf0 100644 --- a/Data-Structures/Graph/Graph3.js +++ b/Data-Structures/Graph/Graph3.js @@ -1,13 +1,13 @@ class Graph { - constructor() { + constructor () { this.adjacencyObject = {} } - addVertex(vertex) { + addVertex (vertex) { if (!this.adjacencyObject[vertex]) this.adjacencyObject[vertex] = [] } - addEdge(vertex1, vertex2) { + addEdge (vertex1, vertex2) { if (this.adjacencyObject[vertex1] && this.adjacencyObject[vertex2]) { this.adjacencyObject[vertex1].push(vertex2) this.adjacencyObject[vertex2].push(vertex1) @@ -16,7 +16,7 @@ class Graph { } } - removeEdge(vertex1, vertex2) { + removeEdge (vertex1, vertex2) { if (this.adjacencyObject[vertex1] && this.adjacencyObject[vertex2]) { this.adjacencyObject[vertex1] = this.adjacencyObject[vertex1].filter( (v) => v !== vertex2 @@ -29,7 +29,7 @@ class Graph { } } - removeVertex(vertex) { + removeVertex (vertex) { if (this.adjacencyObject[vertex]) { while (this.adjacencyObject[vertex].length) { const adjacentVertex = this.adjacencyObject[vertex].pop() @@ -41,14 +41,16 @@ class Graph { } /** - * Return DFS(Depth First Search) List Using Recursive Method + * Return DFS (Depth First Search) List Using Recursive Method */ - DFS(start) { + DFS (start) { + if (!start) return null + const result = [] const visited = {} const adjacencyObject = this.adjacencyObject - function dfs(vertex) { + function dfs (vertex) { if (!vertex) return null visited[vertex] = true result.push(vertex) @@ -66,7 +68,9 @@ class Graph { /** * Return DFS(Depth First Search) List Using Iteration */ - DFS_iterative(start) { + DFSIterative (start) { + if (!start) return null + const stack = [start] const visited = {} visited[start] = true @@ -88,7 +92,9 @@ class Graph { return result } - BFS(start) { + BFS (start) { + if (!start) return null + const queue = [start] const visited = {} visited[start] = true @@ -111,25 +117,4 @@ class Graph { } } -// example -// const g = new Graph() -// g.addVertex('A') -// g.addVertex('B') -// g.addVertex('C') -// g.addVertex('D') -// g.addVertex('E') -// g.addVertex('F') - -// g.addEdge('A', 'B') -// g.addEdge('A', 'C') -// g.addEdge('B', 'D') -// g.addEdge('C', 'E') -// g.addEdge('D', 'E') -// g.addEdge('D', 'F') -// g.addEdge('E', 'F') - -// g.removeVertex('B') - -// console.log(g.BFS('A')) - export { Graph } diff --git a/Data-Structures/Graph/test/Graph3.test.js b/Data-Structures/Graph/test/Graph3.test.js new file mode 100644 index 0000000000..d10cc8da2b --- /dev/null +++ b/Data-Structures/Graph/test/Graph3.test.js @@ -0,0 +1,75 @@ +import { Graph } from '../Graph3' + +describe('Test Graph3', () => { + const g = new Graph() + + // Add Vertices + g.addVertex('A') + g.addVertex('B') + g.addVertex('C') + g.addVertex('D') + g.addVertex('E') + g.addVertex('F') + + // Add Edges + g.addEdge('A', 'B') + g.addEdge('A', 'C') + g.addEdge('B', 'D') + g.addEdge('C', 'E') + g.addEdge('D', 'E') + g.addEdge('D', 'F') + g.addEdge('E', 'F') + + /** + * A - B - D + * | / \ + * C - - E - F + * + * DFS(Iterative): A-C-E-F-D-B + * DFS(Recursive): A-B-D-E-C-F + * BFS: A-B-C-D-E-F + */ + it('Check iterative DFS List', () => { + const iterativeDFSList = g.DFSIterative('A') + expect(iterativeDFSList).toEqual(['A', 'C', 'E', 'F', 'D', 'B']) + }) + + it('Check recursive DFS List', () => { + const recursiveDFSList = g.DFS('A') + expect(recursiveDFSList).toEqual(['A', 'B', 'D', 'E', 'C', 'F']) + }) + + it('Check BFS List', () => { + const BFSList = g.BFS('A') + expect(BFSList).toEqual(['A', 'B', 'C', 'D', 'E', 'F']) + }) + + /** + * Test After Remove 'B' Vertex + * A D + * | / \ + * C - - E - F + * + * DFS(Iterative): A-C-E-F-D + * DFS(Recursive): A-C-E-D-F + * BFS: A-C-E-D-F + */ + + it('Check iterative DFS List After Removing Vertex B', () => { + g.removeVertex('B') + const iterativeDFSList = g.DFSIterative('A') + expect(iterativeDFSList).toEqual(['A', 'C', 'E', 'F', 'D']) + }) + + it('Check recursive DFS List After Removing Vertex B', () => { + g.removeVertex('B') + const recursiveDFSList = g.DFS('A') + expect(recursiveDFSList).toEqual(['A', 'C', 'E', 'D', 'F']) + }) + + it('Check BFS List After Removing Vertex B', () => { + g.removeVertex('B') + const BFSList = g.BFS('A') + expect(BFSList).toEqual(['A', 'C', 'E', 'D', 'F']) + }) +}) From 562ed48b66382b0c47f221d626e1b6ce8ecf7002 Mon Sep 17 00:00:00 2001 From: dongjji Date: Thu, 24 Mar 2022 16:02:45 +0900 Subject: [PATCH 3/3] Remove redundant code (like return undefined) --- Data-Structures/Graph/Graph3.js | 34 +++++++++++---------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/Data-Structures/Graph/Graph3.js b/Data-Structures/Graph/Graph3.js index eed4b60cf0..d5a36bf181 100644 --- a/Data-Structures/Graph/Graph3.js +++ b/Data-Structures/Graph/Graph3.js @@ -8,35 +8,23 @@ class Graph { } addEdge (vertex1, vertex2) { - if (this.adjacencyObject[vertex1] && this.adjacencyObject[vertex2]) { - this.adjacencyObject[vertex1].push(vertex2) - this.adjacencyObject[vertex2].push(vertex1) - } else { - return undefined - } + this.adjacencyObject[vertex1].push(vertex2) + this.adjacencyObject[vertex2].push(vertex1) } removeEdge (vertex1, vertex2) { - if (this.adjacencyObject[vertex1] && this.adjacencyObject[vertex2]) { - this.adjacencyObject[vertex1] = this.adjacencyObject[vertex1].filter( - (v) => v !== vertex2 - ) - this.adjacencyObject[vertex2] = this.adjacencyObject[vertex2].filter( - (v) => v !== vertex1 - ) - } else { - return undefined - } + this.adjacencyObject[vertex1] = this.adjacencyObject[vertex1].filter( + (v) => v !== vertex2 + ) + this.adjacencyObject[vertex2] = this.adjacencyObject[vertex2].filter( + (v) => v !== vertex1 + ) } removeVertex (vertex) { - if (this.adjacencyObject[vertex]) { - while (this.adjacencyObject[vertex].length) { - const adjacentVertex = this.adjacencyObject[vertex].pop() - this.removeEdge(vertex, adjacentVertex) - } - } else { - return undefined + while (this.adjacencyObject[vertex].length) { + const adjacentVertex = this.adjacencyObject[vertex].pop() + this.removeEdge(vertex, adjacentVertex) } }