Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions Data-Structures/Graph/Graph3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
class Graph {
constructor () {
this.adjacencyObject = {}
}

addVertex (vertex) {
if (!this.adjacencyObject[vertex]) this.adjacencyObject[vertex] = []
}

addEdge (vertex1, vertex2) {
this.adjacencyObject[vertex1].push(vertex2)
this.adjacencyObject[vertex2].push(vertex1)
}

removeEdge (vertex1, vertex2) {
this.adjacencyObject[vertex1] = this.adjacencyObject[vertex1].filter(
(v) => v !== vertex2
)
this.adjacencyObject[vertex2] = this.adjacencyObject[vertex2].filter(
(v) => v !== vertex1
)
}

removeVertex (vertex) {
while (this.adjacencyObject[vertex].length) {
const adjacentVertex = this.adjacencyObject[vertex].pop()
this.removeEdge(vertex, adjacentVertex)
}
}

/**
* Return DFS (Depth First Search) List Using Recursive Method
*/
DFS (start) {
if (!start) return null

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
*/
DFSIterative (start) {
if (!start) return null

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) {
if (!start) return null

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
}
}

export { Graph }
75 changes: 75 additions & 0 deletions Data-Structures/Graph/test/Graph3.test.js
Original file line number Diff line number Diff line change
@@ -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'])
})
})