Skip to content

Commit e73b1dd

Browse files
committed
Refactoring DFS and Add tests for BFS and DFS' applications
1 parent 2a005e6 commit e73b1dd

File tree

5 files changed

+98
-38
lines changed

5 files changed

+98
-38
lines changed

src/data-structures/graph/graph.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,36 @@ describe("Graph class test", () => {
2929
test(700, TEST_36);
3030
test(700, TEST_40);
3131
});
32+
33+
test("BFS easy Example", () => {
34+
const easy = `${__dirname}/test-datasets/generic-search/classEg.txt`;
35+
const g = Graph.createListAdj(easy);
36+
const { dist } = g.bfs("s");
37+
expect(dist.get("s")).toBe(0);
38+
expect(dist.get("a")).toBe(1);
39+
expect(dist.get("b")).toBe(1);
40+
expect(dist.get("c")).toBe(2);
41+
expect(dist.get("d")).toBe(2);
42+
expect(dist.get("e")).toBe(3);
43+
});
44+
45+
test("Undirect Components easy Example", () => {
46+
const easy = `${__dirname}/test-datasets/generic-search/undirectComponents.txt`;
47+
const g = Graph.createListAdj(easy);
48+
const components = g.undirectConnectivity();
49+
expect(components[0]).toEqual(["s", "b", "a"]);
50+
expect(components[1]).toEqual(["c", "e", "d"]);
51+
});
52+
53+
test("Topological Sort easy example", () => {
54+
const easy = `${__dirname}/test-datasets/generic-search/topologicalSort.txt`;
55+
const g = Graph.createDirected(easy);
56+
const { labeledOrder, finish } = g.topologicalSort();
57+
expect(labeledOrder.get("t")).toBe(4);
58+
expect(labeledOrder.get("s")).toBe(1);
59+
expect(labeledOrder.get("v")).toBeGreaterThan(1);
60+
expect(labeledOrder.get("v")).toBeLessThan(4);
61+
expect(labeledOrder.get("w")).toBeGreaterThan(1);
62+
expect(labeledOrder.get("w")).toBeLessThan(4);
63+
});
3264
});

src/data-structures/graph/graph.ts

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ class Graph<T> {
333333
};
334334

335335
// Adds both u and v verteces and their edge w
336-
addVertecesAndEdge = (u: T, v: T, w = 0, d = true) => {
336+
addVertecesAndEdge = (u: T, v: T, w = 1, d = true) => {
337337
this.addVertex(u);
338338
this.addVertex(v);
339339
if (d) {
@@ -525,9 +525,8 @@ class Graph<T> {
525525
} else {
526526
split = line.trim().split(" ");
527527
if (!w) {
528-
g.addVertecesAndEdge(split[0], split[1], 0, d);
528+
g.addVertecesAndEdge(split[0], split[1], 1, d);
529529
} else {
530-
// Avoid duplications!
531530
g.addVertecesAndEdge(split[0], split[1], parseInt(split[2]), d);
532531
}
533532

@@ -537,7 +536,11 @@ class Graph<T> {
537536
// check if the last line is empty
538537
if (line !== "") {
539538
split = line.trim().split(" ");
540-
g.addVertecesAndEdge(split[0], split[1]);
539+
if (!w) {
540+
g.addVertecesAndEdge(split[0], split[1], 1, d);
541+
} else {
542+
g.addVertecesAndEdge(split[0], split[1], parseInt(split[2]), d);
543+
}
541544
}
542545
return g;
543546
};
@@ -562,7 +565,7 @@ class Graph<T> {
562565

563566
// Returns: a list of all verteces found (in the order of dequeue)
564567
// the parent of each visited vertex
565-
// the distance of s to each visited vertex
568+
// the distance from s to each visited vertex
566569
// all visited verteces
567570
bfs = (s: T) => {
568571
// the order of each vertex is dequeue (Array of Keys)
@@ -619,56 +622,66 @@ class Graph<T> {
619622
};
620623

621624
// dfs iterative
625+
// Returns: a list of all verteces found (in the order of dequeue)
626+
// the parent of each visited vertex
627+
// all visited verteces
622628
dfs = (s: T) => {
629+
// popped stack order
623630
const result: Array<T> = new Array();
624-
const dist: Map<T, number> = new Map();
625631
const parents: Map<T, null | T> = new Map();
632+
// a node is visited when it is popped from the stack
626633
const visited: Map<T, boolean> = new Map();
627-
// key to label order
628-
const labeledOrder: Map<T, number | null> = new Map();
629-
// finish order
630-
const finish: Array<T> = new Array();
631634
const stack = new Stack();
632-
// add s tothe stack
633635
stack.push(s);
634-
// mark s as visited
635-
visited.set(s, true);
636-
dist.set(s, 0);
636+
parents.set(s, null);
637637
let v: Node;
638-
let i = 0;
638+
639639
while (stack.size !== 0) {
640640
// take from the top of the stack
641641
v = stack.pop()!;
642-
result.push(v.key);
643-
// add parent of v wich is the last one poped
644-
if (i === 0) {
645-
parents.set(v.key, null);
646-
} else {
647-
parents.set(v.key, result[i - 1]);
642+
if (!visited.get(v.key)) {
643+
result.push(v.key);
644+
visited.set(v.key, true);
648645
}
649-
i++;
650-
// for every edge of v
651646
this.list.get(v.key)!.forEach((u) => {
652-
// v unvisited
653647
if (!visited.get(u.node)) {
654-
// mark u as visited
655-
visited.set(u.node, true);
656-
// add u to the stack
648+
parents.set(u.node, v.key);
657649
stack.push(u.node);
658-
// calc dist
659-
dist.set(u.node, dist.get(v.key)! + 1);
660650
}
661651
});
662-
if (!labeledOrder.get(v.key)) {
663-
labeledOrder.set(v.key, this.currentLabel);
664-
this.currentLabel!++;
665-
finish.push(v.key);
666-
}
667652
}
668653
return {
669654
result,
670655
parents,
671-
dist,
656+
visited,
657+
};
658+
};
659+
660+
// dfs recursive
661+
// Returns: a list of all verteces found (in the order of dequeue)
662+
// the parent of each visited vertex
663+
// all visited verteces
664+
dfsRec = (
665+
s: T,
666+
visited: Map<T, boolean> = new Map(),
667+
labeledOrder: Map<T, number | null> = new Map(),
668+
finish: Array<T> = new Array()
669+
) => {
670+
// mark s as visited
671+
visited.set(s, true);
672+
// for every edge of s
673+
this.list.get(s)!.forEach((u) => {
674+
if (!visited.get(u.node)) {
675+
// recursive call
676+
this.dfsRec(u.node, visited, labeledOrder, finish);
677+
}
678+
});
679+
if (!labeledOrder.get(s)) {
680+
labeledOrder.set(s, this.currentLabel);
681+
this.currentLabel!--;
682+
finish.push(s);
683+
}
684+
return {
672685
labeledOrder,
673686
visited,
674687
finish,
@@ -682,11 +695,10 @@ class Graph<T> {
682695
const visited: Map<T, boolean> = new Map();
683696
const finish: Array<T> = new Array();
684697
// to keep track of ordering
685-
this.currentLabel = 0;
686-
let r;
698+
this.currentLabel = this.list.size;
687699
for (let [u] of this.list) {
688700
if (!visited.get(u)) {
689-
const r = this.dfs(u);
701+
const r = this.dfsRec(u);
690702
// update values
691703
r.visited.forEach((value, key) => {
692704
visited.set(key, value);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
s a b
2+
a s c
3+
b s c d
4+
c a b d e
5+
d b c e
6+
e c d
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
s v
2+
s w
3+
v t
4+
w t
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
s a b
2+
a s
3+
b s
4+
c d e
5+
d c e
6+
e c d

0 commit comments

Comments
 (0)