A collection of Nodes and Edges
A graph is great establishing relationships between Nodes
graph LR
a --> b
b --> c
a --> c
c --> d
graph LR
a --- b
b --- c
a --- c
c --- d
Let Following be a Graph
graph LR
a --> b
a --> c
b --> d
c --> e
d --> f
Adjacency Matrix
Adjacency List
let gr = [
[0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]
];
let gr = [
a: [c, b],
b: [d],
c: [e],
d: [f]
e: []
f: []
}
<aside> š” Can you see the amount of space being wasted to store this simple graph in a adjacency matrix? For storing 5 relationships I have to always use $O(n*e)$ space. What if we could only save the Relationships instead of Non-Relationships? Therefore for sparse graphs like this, adhacency lists are optimal
</aside>
DFS Traversal goes deep in a directon untill it can go no more.
DFS uses stack Data Structure
DFS visits nodes linearly
BFS is traversal that traverses āNearest Neighbour Firstā.
BFS Queue Data structure.
BFS visits nodes radially
function dfs(graph, source='a') {
let stack = [source];
while(stack.length > 0) {
let current = stack.pop();
console.log(current)
for(let neighbour of gr[current]) {
stack.push(neighbour)
}
}
}
function bfs(gr, source) {
let queue = [source];
//repeat till queue has elements
while(queue.length > 0) {
// pop and print current element
let current = queue.pop();
console.log(current);
//Add all neighbouring elements in queue
for(let neighbour of gr[current]) {
queue.unshift(neighbour)
}
}
}