diff --git a/problem-1/BFS.js b/problem-1/BFS.js index c9a3539..5af84d9 100644 --- a/problem-1/BFS.js +++ b/problem-1/BFS.js @@ -1,3 +1,6 @@ +const { Queue } = require('../data-structure/Queue'); +const { Stack } = require('../data-structure/Stack'); + class BFS { #marked = []; @@ -12,13 +15,48 @@ class BFS { this.#bfs(graph, s); } + #visit(v) { + this.#marked[v] = true; + } + #bfs(graph, s) { + this.#visit(s); + + const queue = new Queue(); + + queue.enqueue(s); + + while (!queue.isEmpty()) { + const v = queue.dequeue(); + + for (const w of graph.adj(v)) { + if (!this.#marked[w]) { + this.#visit(w); + this.#edgeTo[w] = v; + queue.enqueue(w); + } + } + } } hasPathTo(v) { + return this.#marked[v]; } pathTo(v) { + if (!this.hasPathTo(v)) { + return; + } + + const path = new Stack(); + + for (let i = v; i !== this.#s; i = this.#edgeTo[i]) { + path.push(i); + } + + path.push(this.#s); + + return path; } } diff --git a/problem-1/DFS.js b/problem-1/DFS.js index ed14f13..c8ef632 100644 --- a/problem-1/DFS.js +++ b/problem-1/DFS.js @@ -8,19 +8,52 @@ class DFS { #s; constructor(graph, s) { + // 정점 방문 여부 this.#marked = Array.from({ length: graph.v() }, () => false); + + // 이전 경로 this.#edgeTo = Array.from({ length: graph.v() }, () => undefined); + + // 시작점 this.#s = s; this.#dfs(graph, s); } - #dfs(grpah, v) { + #dfs(graph, v) { + // 정점을 방문했다고 표시 + this.#marked[v] = true; + + // 인접한 정점을 순회한다 + for (const w of graph.adj(v)) { + // 방문하지 않았을 경우 + if (!this.#marked[w]) { + // w에 v로 부터 왔다고 기록한다 + this.#edgeTo[w] = v; + this.#dfs(graph, w); + } + } } hasPathTo(v) { + // DFS는 모든 정점을 방문하기 때문에 연결되어 있다면 + // #marked[v]가 true일 수 밖에 없다. + return this.#marked[v]; } pathTo(v) { + if (!this.hasPathTo(v)) { + return; + } + + const path = new Stack(); + + for (let i = v; i !== this.#s; i = this.#edgeTo[i]) { + path.push(i); + } + + path.push(this.#s); + + return path; } } diff --git a/problem-1/Graph.js b/problem-1/Graph.js index 37762f0..9923732 100644 --- a/problem-1/Graph.js +++ b/problem-1/Graph.js @@ -1,12 +1,15 @@ const { Bag } = require('../data-structure/Bag'); class Graph { + // 정점의 개수 #v; + // 간선의 개수 #e; #adj = []; + // v = 정점의 개수 constructor(v) { this.#v = v; for (let i = 0; i < this.#v; i++) { @@ -17,17 +20,22 @@ class Graph { addEdge(v, w) { this.#adj[v].add(w); this.#adj[w].add(v); + + // 간선의 개수 증가 this.#e++; } + // 정점에 인접한 정점들을 반환 adj(v) { return this.#adj[v]; } + // 정점의 개수 반환 v() { return this.#v; } + // 간선의 개수 반환 e() { return this.#e; }