Skip to content

feat: Added new graphs algorithms with doc strings #1440

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
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
115 changes: 115 additions & 0 deletions Graphs/Graph.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
class Graph {
constructor() {
this.adjacencyMap = {}
}

addVertex(vertex) {
this.adjacencyMap[vertex] = []
}

containsVertex(vertex) {
return typeof this.adjacencyMap[vertex] !== 'undefined'
}

addEdge(vertex1, vertex2) {
if (this.containsVertex(vertex1) && this.containsVertex(vertex2)) {
this.adjacencyMap[vertex1].push(vertex2)
this.adjacencyMap[vertex2].push(vertex1)
}
}

/**
* Prints the graph using the given output function.
*
* @param {function(value)} output The output function to use.
*/

printGraph(output = (value) => console.log(value)) {
const keys = Object.keys(this.adjacencyMap)
for (const i of keys) {
const values = this.adjacencyMap[i]
let vertex = ''
for (const j of values) {
vertex += j + ' '
}
output(i + ' -> ' + vertex)
}
}

/**
* Prints the Breadth first traversal of the graph from source.
*
* @param {number} source The source vertex to start BFS.
* @param {function(value)} output The output function to use.
*/

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

visited.add(node)
output(`Visited node ${node} at level ${level}.`)
for (const next of this.adjacencyMap[node]) {
queue.push([next, level + 1]) // level 1 more than current
}
}
}

/**
* Prints the Depth first traversal of the graph from source.
*
* @param {number} source The source vertex to start DFS.
* @param {function(value)} output The output function to use.
*/

dfs(source, visited = new Set(), output = (value) => console.log(value)) {
if (visited.has(source)) {
// visited
return
}

output(`Visited node ${source}`)
visited.add(source)
for (const neighbour of this.adjacencyMap[source]) {
this.dfs(neighbour, visited, output)
}
}
}

const example = () => {
const g = new Graph()
g.addVertex(1)
g.addVertex(2)
g.addVertex(3)
g.addVertex(4)
g.addVertex(5)
g.addEdge(1, 2)
g.addEdge(1, 3)
g.addEdge(2, 4)
g.addEdge(2, 5)

// Graph
// 1 -> 2 3
// 2 -> 1 4 5
// 3 -> 1
// 4 -> 2
// 5 -> 2

// Printing the adjacency list
// g.printGraph()

// Breadth first search at node 1
g.bfs(1)

// Depth first search at node 1
g.dfs(1)
}

export { Graph, example }
71 changes: 71 additions & 0 deletions Graphs/Graph2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// create a graph class
class Graph {
// defining vertex array and
// adjacent list

/**
* Create a graph with the number of vertices
* @param {number} noOfVertices the number of vertices of the graph
*/
constructor(noOfVertices) {
this.noOfVertices = noOfVertices
this.AdjList = new Map()
}

// functions to be implemented

// addVertex(v)
// addEdge(v, w)
// printGraph()

// bfs(v)
// dfs(v)

// add vertex to the graph
addVertex(v) {
// initialize the adjacent list with a
// null array

this.AdjList.set(v, [])
}

// add edge to the graph
addEdge(v, w) {
// get the list for vertex v and put the
// vertex w denoting edge between v and w
this.AdjList.get(v).push(w)

// Since graph is undirected,
// add an edge from w to v also
this.AdjList.get(w).push(v)
}

// Prints the vertex and adjacency list

/**
* @param {function(value)} output The output function use
*/
printGraph(output = (value) => console.log(value)) {
// get all the vertices
const getKeys = this.AdjList.keys()

// iterate over the vertices
for (const i of getKeys) {
// get the corresponding adjacency list
// for the vertex
const getValues = this.AdjList.get(i)
let conc = ''

// iterate over the adjacency list
// concatenate the values into a string
for (const j of getValues) {
conc += j + ' '
}

// print the vertex and its adjacency list
output(i + ' -> ' + conc)
}
}
}

export { Graph }
126 changes: 126 additions & 0 deletions Graphs/Graph3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
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
*
* @param {number} start The start vertex.
* @returns {Array<number>} The DFS list.
*
*/

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
*
* @param {number} start The start vertex.
* @returns {Array<number>} The DFS list.
*/


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
}

/**
* Return BFS (Breadth First Search) List
*
* @param {number} start The start vertex.
* @returns {Array<number>} The BFS list.
*/

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 }