Skip to content

Commit f9fbbab

Browse files
feat: Added new graphs algorithms with doc strings
1 parent 1de5ab7 commit f9fbbab

File tree

3 files changed

+312
-0
lines changed

3 files changed

+312
-0
lines changed

Graphs/Graph.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
class Graph {
2+
constructor() {
3+
this.adjacencyMap = {}
4+
}
5+
6+
addVertex(vertex) {
7+
this.adjacencyMap[vertex] = []
8+
}
9+
10+
containsVertex(vertex) {
11+
return typeof this.adjacencyMap[vertex] !== 'undefined'
12+
}
13+
14+
addEdge(vertex1, vertex2) {
15+
if (this.containsVertex(vertex1) && this.containsVertex(vertex2)) {
16+
this.adjacencyMap[vertex1].push(vertex2)
17+
this.adjacencyMap[vertex2].push(vertex1)
18+
}
19+
}
20+
21+
/**
22+
* Prints the graph using the given output function.
23+
*
24+
* @param {function(value)} output The output function to use.
25+
*/
26+
27+
printGraph(output = (value) => console.log(value)) {
28+
const keys = Object.keys(this.adjacencyMap)
29+
for (const i of keys) {
30+
const values = this.adjacencyMap[i]
31+
let vertex = ''
32+
for (const j of values) {
33+
vertex += j + ' '
34+
}
35+
output(i + ' -> ' + vertex)
36+
}
37+
}
38+
39+
/**
40+
* Prints the Breadth first traversal of the graph from source.
41+
*
42+
* @param {number} source The source vertex to start BFS.
43+
* @param {function(value)} output The output function to use.
44+
*/
45+
46+
bfs(source, output = (value) => console.log(value)) {
47+
const queue = [[source, 0]] // level of source is 0
48+
const visited = new Set()
49+
50+
while (queue.length) {
51+
const [node, level] = queue.shift() // remove the front of the queue
52+
if (visited.has(node)) {
53+
// visited
54+
continue
55+
}
56+
57+
visited.add(node)
58+
output(`Visited node ${node} at level ${level}.`)
59+
for (const next of this.adjacencyMap[node]) {
60+
queue.push([next, level + 1]) // level 1 more than current
61+
}
62+
}
63+
}
64+
65+
/**
66+
* Prints the Depth first traversal of the graph from source.
67+
*
68+
* @param {number} source The source vertex to start DFS.
69+
* @param {function(value)} output The output function to use.
70+
*/
71+
72+
dfs(source, visited = new Set(), output = (value) => console.log(value)) {
73+
if (visited.has(source)) {
74+
// visited
75+
return
76+
}
77+
78+
output(`Visited node ${source}`)
79+
visited.add(source)
80+
for (const neighbour of this.adjacencyMap[source]) {
81+
this.dfs(neighbour, visited, output)
82+
}
83+
}
84+
}
85+
86+
const example = () => {
87+
const g = new Graph()
88+
g.addVertex(1)
89+
g.addVertex(2)
90+
g.addVertex(3)
91+
g.addVertex(4)
92+
g.addVertex(5)
93+
g.addEdge(1, 2)
94+
g.addEdge(1, 3)
95+
g.addEdge(2, 4)
96+
g.addEdge(2, 5)
97+
98+
// Graph
99+
// 1 -> 2 3
100+
// 2 -> 1 4 5
101+
// 3 -> 1
102+
// 4 -> 2
103+
// 5 -> 2
104+
105+
// Printing the adjacency list
106+
// g.printGraph()
107+
108+
// Breadth first search at node 1
109+
g.bfs(1)
110+
111+
// Depth first search at node 1
112+
g.dfs(1)
113+
}
114+
115+
export { Graph, example }

Graphs/Graph2.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// create a graph class
2+
class Graph {
3+
// defining vertex array and
4+
// adjacent list
5+
6+
/**
7+
* Create a graph with the number of vertices
8+
* @param {number} noOfVertices the number of vertices of the graph
9+
*/
10+
constructor(noOfVertices) {
11+
this.noOfVertices = noOfVertices
12+
this.AdjList = new Map()
13+
}
14+
15+
// functions to be implemented
16+
17+
// addVertex(v)
18+
// addEdge(v, w)
19+
// printGraph()
20+
21+
// bfs(v)
22+
// dfs(v)
23+
24+
// add vertex to the graph
25+
addVertex(v) {
26+
// initialize the adjacent list with a
27+
// null array
28+
29+
this.AdjList.set(v, [])
30+
}
31+
32+
// add edge to the graph
33+
addEdge(v, w) {
34+
// get the list for vertex v and put the
35+
// vertex w denoting edge between v and w
36+
this.AdjList.get(v).push(w)
37+
38+
// Since graph is undirected,
39+
// add an edge from w to v also
40+
this.AdjList.get(w).push(v)
41+
}
42+
43+
// Prints the vertex and adjacency list
44+
45+
/**
46+
* @param {function(value)} output The output function use
47+
*/
48+
printGraph(output = (value) => console.log(value)) {
49+
// get all the vertices
50+
const getKeys = this.AdjList.keys()
51+
52+
// iterate over the vertices
53+
for (const i of getKeys) {
54+
// get the corresponding adjacency list
55+
// for the vertex
56+
const getValues = this.AdjList.get(i)
57+
let conc = ''
58+
59+
// iterate over the adjacency list
60+
// concatenate the values into a string
61+
for (const j of getValues) {
62+
conc += j + ' '
63+
}
64+
65+
// print the vertex and its adjacency list
66+
output(i + ' -> ' + conc)
67+
}
68+
}
69+
}
70+
71+
export { Graph }

Graphs/Graph3.js

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
class Graph {
2+
3+
constructor() {
4+
this.adjacencyObject = {}
5+
}
6+
7+
addVertex(vertex) {
8+
if (!this.adjacencyObject[vertex]) this.adjacencyObject[vertex] = []
9+
}
10+
11+
addEdge(vertex1, vertex2) {
12+
this.adjacencyObject[vertex1].push(vertex2)
13+
this.adjacencyObject[vertex2].push(vertex1)
14+
}
15+
16+
removeEdge(vertex1, vertex2) {
17+
this.adjacencyObject[vertex1] = this.adjacencyObject[vertex1].filter(
18+
(v) => v !== vertex2
19+
)
20+
this.adjacencyObject[vertex2] = this.adjacencyObject[vertex2].filter(
21+
(v) => v !== vertex1
22+
)
23+
}
24+
25+
removeVertex(vertex) {
26+
while (this.adjacencyObject[vertex].length) {
27+
const adjacentVertex = this.adjacencyObject[vertex].pop()
28+
this.removeEdge(vertex, adjacentVertex)
29+
}
30+
}
31+
32+
/**
33+
* Return DFS (Depth First Search) List Using Recursive Method
34+
*
35+
* @param {number} start The start vertex.
36+
* @returns {Array<number>} The DFS list.
37+
*
38+
*/
39+
40+
DFS(start) {
41+
if (!start) return null
42+
43+
const result = []
44+
const visited = {}
45+
const adjacencyObject = this.adjacencyObject
46+
47+
function dfs(vertex) {
48+
if (!vertex) return null
49+
visited[vertex] = true
50+
result.push(vertex)
51+
adjacencyObject[vertex].forEach((neighbor) => {
52+
if (!visited[neighbor]) {
53+
dfs(neighbor)
54+
}
55+
})
56+
}
57+
58+
dfs(start)
59+
return result
60+
}
61+
62+
/**
63+
* Return DFS (Depth First Search) List Using Iteration
64+
*
65+
* @param {number} start The start vertex.
66+
* @returns {Array<number>} The DFS list.
67+
*/
68+
69+
70+
DFSIterative(start) {
71+
if (!start) return null
72+
73+
const stack = [start]
74+
const visited = {}
75+
visited[start] = true
76+
77+
const result = []
78+
let currentVertex
79+
80+
while (stack.length) {
81+
currentVertex = stack.pop()
82+
result.push(currentVertex)
83+
84+
this.adjacencyObject[currentVertex].forEach((neighbor) => {
85+
if (!visited[neighbor]) {
86+
visited[neighbor] = true
87+
stack.push(neighbor)
88+
}
89+
})
90+
}
91+
return result
92+
}
93+
94+
/**
95+
* Return BFS (Breadth First Search) List
96+
*
97+
* @param {number} start The start vertex.
98+
* @returns {Array<number>} The BFS list.
99+
*/
100+
101+
BFS(start) {
102+
if (!start) return null
103+
104+
const queue = [start]
105+
const visited = {}
106+
visited[start] = true
107+
108+
let currentVertex
109+
const result = []
110+
111+
while (queue.length) {
112+
currentVertex = queue.shift()
113+
result.push(currentVertex)
114+
115+
this.adjacencyObject[currentVertex].forEach((neighbor) => {
116+
if (!visited[neighbor]) {
117+
visited[neighbor] = true
118+
queue.push(neighbor)
119+
}
120+
})
121+
}
122+
return result
123+
}
124+
}
125+
126+
export { Graph }

0 commit comments

Comments
 (0)