From 9b2e31aa325988c4524b5a51562de2a030597276 Mon Sep 17 00:00:00 2001 From: Victoria Date: Sat, 20 Oct 2018 13:53:31 +0300 Subject: [PATCH 1/2] feat: Graph bfs --- graphs/bfs.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 graphs/bfs.js diff --git a/graphs/bfs.js b/graphs/bfs.js new file mode 100644 index 0000000000..231f5f63b5 --- /dev/null +++ b/graphs/bfs.js @@ -0,0 +1,44 @@ +/* + A non-recursive implementation of bfs with worst-case space complexity O(|E|) +*/ + +function Vertex (name, neighbours) { + this.name = name; + this.neighbours = neighbours; + } + + function bfs (root) { + var visited = {} + var stack = [] + + stack.push(root) + while(!!stack.length) { + var vertex = stack.shift() + + if (!visited[vertex.name]) { + visited[vertex.name] = true + console.log('Visiting vertex ', vertex.name) + + var len = vertex.neighbours.length + for (var index = 0; index < len; index++) { + stack.push(vertex.neighbours[index]) + } + } + } + } + + var root = new Vertex('root', [ + new Vertex('child 1', [ + new Vertex('grandchild 1', []), new Vertex('grandchild 2', []) + ]), + new Vertex('child 2', [ + new Vertex('grandchild 3', []), + ]), + new Vertex('child 3', [ + new Vertex('grandchild 4', [ + new Vertex('grandgrandchild 1', []) + ]), + ]), + ]) + + bfs(root) \ No newline at end of file From 15daa518be9eeecf4b45733c27594109f2b282f7 Mon Sep 17 00:00:00 2001 From: Victoria Date: Sat, 20 Oct 2018 14:00:03 +0300 Subject: [PATCH 2/2] Feat: graphsBreadFirstSearch --- graphs/breadth-first-search.js | 92 ++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 graphs/breadth-first-search.js diff --git a/graphs/breadth-first-search.js b/graphs/breadth-first-search.js new file mode 100644 index 0000000000..45bd559b19 --- /dev/null +++ b/graphs/breadth-first-search.js @@ -0,0 +1,92 @@ +// Breadth-first Search + +class Graph { + constructor(n) { + // the number of vertexes + this.n = n; + + // adjacency list representation + this.adjList = Array.from(Array(n), () => []); + } + + addDirectedEdge(from, to) { + this.adjList[from].push(to); + } + + addEdge(v, w) { + this.adjList[v].push(w); + this.adjList[w].push(v); + } + + // s - the number of the starting vertex + // to - the number of the end vertex + breadthFirstSearch(s) { + if (s < 0 || s >= this.n) { + throw Error('Wrong starting vertex'); + } + + let queue = []; + let visited = new Array(this.n); + let path = new Array(this.n); + let time = new Array(this.n).fill(-1); + + // The first iteration + queue.push(s); + visited[s] = true; + path[s] = -1; + time[s] = 0; + + while (queue.length > 0) { + let v = queue.shift(); + + for (let to of this.adjList[v]) { + if (!visited[to]) { + queue.push(to); + visited[to] = true; + path[to] = v; + time[to] = time[v] + 1; + } + } + } + + return { visited, path, time }; + } + + // Array of distances to vertexes from the starting one + BFS(s) { + return this.breadthFirstSearch(s).time; + } + + findPathToVertex(s, to) { + let { visited, path } = this.breadthFirstSearch(s); + + if (!visited[to]) { + return 'No path'; + } + + let realPath = []; + + for (let v = to; v !== -1; v = path[v]) { + realPath.unshift(v); + } + + return realPath.reduce((out, i) => `${out} ${i}`, `Path from ${s} to ${to}:`); + } +} + +function test() { + let g = new Graph(5); + + g.addDirectedEdge(0, 1); + g.addDirectedEdge(1, 2); + g.addDirectedEdge(2, 3); + g.addDirectedEdge(3, 3); + g.addDirectedEdge(4, 2) + g.addEdge(2, 0); + + + console.log(g.BFS(2)); + console.log(g.findPathToVertex(4, 1)); +} + +test(); \ No newline at end of file