mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-05 00:01:37 +08:00
merge: Add Graph3 (add DFS in Iterative Way) (#944)
* Add Graph3 (add DFS in Iterative Way) * Remove example code and add test code (Graph3) * Remove redundant code (like return undefined)
This commit is contained in:
108
Data-Structures/Graph/Graph3.js
Normal file
108
Data-Structures/Graph/Graph3.js
Normal file
@ -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
Data-Structures/Graph/test/Graph3.test.js
Normal file
75
Data-Structures/Graph/test/Graph3.test.js
Normal file
@ -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'])
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user