DFS/ BFS
๐๋ํ์ ๊ทธ๋ํ(Graph) ํ์ ์๊ณ ๋ฆฌ์ฆ์ธ DFS/BFS๋ฅผ ์๊ฐํฉ๋๋ค.
๊ทธ๋ํ(Graph)๋ ๋ญ๊น?
๊ทธ๋ํ(Graph) ๋ ์ ์ (
vertex
, ๋ ธ๋)๊ณผ ๊ฐ์ (edge
)๋ก ๊ตฌ์ฑ๋ ์ ํํ(finite) ์๋ฃ๊ตฌ์กฐ ์ ๋๋ค.๋ ์ ์ (๋ ธ๋)๊ฐ ๊ฐ์ ์ผ๋ก ์ฐ๊ฒฐ๋๋ฉด '๋ ๋ ธ๋๋ ์ธ์ (Adjacent)ํ๋ค' ๋ผ๊ณ ํฉ๋๋ค.
ํ์ด์ค๋ถ, ์ธ์คํ๊ทธ๋จ ๊ฐ์ ์์ ๋คํธ์ํฌ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๊ทธ๋ํ ๊ตฌ์กฐ๋ก ๋ง๋ค์ด์ ธ ์์ต๋๋ค. ๊ทธ๋ํ ๊ตฌ์กฐ๋ฅผ ํตํด ์ฌ๋๋ค(
node
) ์ฌ์ด์ ๊ด๊ณ(edge
) ๋ฅผ ์ฝ๊ฒ ํ์ํ ์ ์์ต๋๋ค.
๊ทธ๋ํ ํ์
ํ๋์ ์ ์ (๋ ธ๋)์์ ๋ชจ๋ ๋ ธ๋๋ฅผ ํ ๋ฒ์ฉ ํ์(๋ฐฉ๋ฌธ) ํ๋ ๊ฒ์ ๋งํฉ๋๋ค.
DFS(Depth-First Search, ๊น์ด ์ฐ์ ํ์)
๊ทธ๋ํ์ ์ต๋ ๊น์ด๊น์ง ํ์ํ ํ, ๋ค๋ฅธ ๊ฒฝ๋ก๋ก ์ด๋ํ์ฌ ํ์ํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
์์ ๋ ธ๋์์ ์ต๋ํ ๋ฉ๋ฆฌ ์๋ ๋ ธ๋ ๋ฅผ ์ฐ์ ํ์ํฉ๋๋ค.
DFS๋ฅผ ํ์ฉํ์ฌ ๋ฏธ๋ก์ฐพ๊ธฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. ๋ฏธ๋ก ์์ ๊ธธ์ ๊ฐ์ (
edge
)์ผ๋ก, ๋ง๋ค๋ฅธ ์ง์ ์ ์ ์ (node
)์ผ๋ก ๋ณด๊ณ ๋ฏธ๋ก์ ๋์ฐฉ์ ์ ๋๋ฌํ ๋๊น์ง ๊ฐ ๊ฒฝ๋ก์ ์ต๋ ๊น์ด๊น์ง ํ์ํฉ๋๋ค. ํ์ฌ ์ ํํ ๊ฒฝ๋ก๊ฐ ๋ง๋ค๋ฅธ ๊ณจ๋ชฉ์ ๋ถ๋ชํ๋ฉด ๋๋์๊ฐ์(๋ฐฑํธ๋ํน) ๋ค๋ฅธ ๊ฒฝ๋ก๋ฅผ ํ์ํฉ๋๋ค.์คํ๊ณผ ์ฌ๊ทํจ์๋ฅผ ์ด์ฉํ์ฌ ๊ตฌํํ ์ ์์ต๋๋ค.
DFS ๊ตฌํ ์์
class Graph { constructor() { this.adjacencyList = {}; } // ์ ์ (๋ ธ๋) ์ถ๊ฐ addVertex(vertex) { if (!this.adjacencyList[vertex]) this.adjacencyList[vertex] = []; return this.adjacencyList; } // ๊ฐ์ ์ถ๊ฐ addEdge(vertex1, vertex2) { this.adjacencyList[vertex1].push(vertex2); this.adjacencyList[vertex2].push(vertex1); return this.adjacencyList; } // ํ์ ์์ ๋ ธ๋ ์ธ์ DFS(start) { const result = []; // ํ์ ๊ฒฐ๊ณผ ๋ฐฐ์ด const visited = {}; // ๋ฐฉ๋ฌธํ ๋ ธ๋ ์ฒดํฌ(๊ฐ ๋ ธ๋๋ฅผ ํ ๋ฒ์ฉ๋ง ์ฒ๋ฆฌํ๋๋ก) const adjacencyList = this.adjacencyList; function dfs(vertex) { // ์ ์ ์ด ๋น ๊ฐ์ด๋ฉด null์ ๋ฐํ if (!vertex) return null; // ์์ ๋ ธ๋๋ฅผ ์คํ์ pushํ๊ณ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ visited[vertex] = true; // ํ์ ๊ฒฐ๊ณผ ๋ฐฐ์ด์ ๋ ธ๋ push result.push(vertex); // ์ธ์ ๋ฆฌ์คํธ๋ฅผ ์ํํ๋ฉด์ ํ์ฌ ๋ ธ๋์ ์ฐ๊ฒฐ๋ ๋ค๋ฅธ ๋ ธ๋ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ adjacencyList[vertex].forEach((v) => { // ๋ฐฉ๋ฌธํ์ง ์์ ์ธ์ ๋ ธ๋ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ(์ฌ๊ท) if (!visited[v]) dfs(v); }); } dfs(start); return result; } } const graph = new Graph(); graph.addVertex("A"); graph.addVertex("B"); graph.addVertex("C"); graph.addVertex("D"); graph.addVertex("E"); graph.addVertex("F"); graph.addEdge("A", "B"); graph.addEdge("A", "C"); graph.addEdge("B", "D"); graph.addEdge("C", "E"); graph.addEdge("D", "E"); graph.addEdge("D", "F"); graph.addEdge("E", "F"); graph.DFS("A") // ["A", "B", "D", "E", "C", "F"]
BFS(-First Search, ๋๋น ์ฐ์ ํ์)
๊ทธ๋ํ์ ๊ทผ์ ๋ ธ๋๋ถํฐ ํ์ํ ํ, ๋ค๋ฅธ ๊ฒฝ๋ก๋ก ์ด๋ํ์ฌ ํ์ํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
์์ ๋ ธ๋์์ ์ต๋ํ ๊ฐ๊น์ด ๋ ธ๋(์ด์ ๋ ธ๋) ๋ถํฐ ์ฐ์ ํ์ํฉ๋๋ค.
BFS๋ P2P ํ์ผ ๋คํธ์ํฌ์์ ํผ์ด(peer) ๋ ธ๋๋ฅผ ํ์ํ ๋ ํ์ฉํ ์ ์์ต๋๋ค. BFS๋ฅผ ํ์ฉํด ๊ฐ์ฅ ๊ฐ๊น์ด ์ด์ ๋ ธ๋๋ง ๋น ๋ฅด๊ฒ ํ์ํ ์ ์์ต๋๋ค.
ํ๋ฅผ ์ด์ฉํ์ฌ ๊ตฌํํ ์ ์์ต๋๋ค.
BFS ๊ตฌํ ์์
class Graph { constructor() { this.adjacencyList = {}; } // ์ ์ (๋ ธ๋) ์ถ๊ฐ addVertex(vertex) { if (!this.adjacencyList[vertex]) this.adjacencyList[vertex] = []; return this.adjacencyList; } // ๊ฐ์ ์ถ๊ฐ addEdge(vertex1, vertex2) { this.adjacencyList[vertex1].push(vertex2); this.adjacencyList[vertex2].push(vertex1); return this.adjacencyList; } BFS(start) { const result = []; const visited = {}; let vertex; // ํ์ฌ ๋ ธ๋ const adjacencyList = this.adjacencyList; // ํ์ ์์ ๋ ธ๋๋ฅผ ํ์ ๋ฃ๊ณ , ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ const queue = [start]; visited[start] = true; // ํ๊ฐ ๋น์ด์์ ๋๊น์ง ๋ฐ๋ณต while (queue.length) { // console.log(queue); vertex = queue.shift(); // result.push(vertex); // ์ธ์ ๋ฆฌ์คํธ๋ฅผ ์ํํ์ฌ ๋ฐฉ๋ฌธํ์ง ์์ ์ธ์ ๋ ธ๋ // ํ์ pushํ๊ณ , ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ adjacencyList[vertex].forEach((v) => { if (!visited[v]) { queue.push(v); visited[v] = true; } }); } return result; } } const graph = new Graph(); graph.addVertex("A"); graph.addVertex("B"); graph.addVertex("C"); graph.addVertex("D"); graph.addVertex("E"); graph.addVertex("F"); graph.addEdge("A", "B"); graph.addEdge("A", "C"); graph.addEdge("B", "D"); graph.addEdge("C", "E"); graph.addEdge("D", "E"); graph.addEdge("D", "F"); graph.addEdge("E", "F"); graph.BFS("A") // ["A", "B", "C", "D", "E", "F"]
โป Big-O
์๊ฐ ๋ณต์ก๋๋ ๋ ํ์ ์๊ณ ๋ฆฌ์ฆ ๋ชจ๋
O(N)
(N: ๊ทธ๋ํ ๋ ธ๋์ ๊ฐ์) ์ ๋๋ค.๊ณต๊ฐ ๋ณต์ก๋๋ DFS๋ณด๋ค BFS ์๋์ ์ผ๋ก ํฝ๋๋ค.(๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ ์ฐจ์ง)
๐ก์ ๋ฆฌ
ํญ๋ชฉ
DFS
BFS
์ํ
๊น์ด
๋์ด
์๋ฃ๊ตฌ์กฐ
์คํ(LIFO)
ํ(FIFO)
์ต์ ํ
โ
โญ๏ธ
๋ฌดํ๋ฃจํ
โญ๏ธ
โ
ํน์ง
๋ฐฑํธ๋ํน
์ต์ ํ
BFS๋ ํ์ํด์ผ ํ ๊ทธ๋ํ์ ๊น์ด๊ฐ ๋ ธ๋๋ง๋ค ๋ค๋ฅด๊ฑฐ๋ ๋จ์ผ ๋๋ต์ด ํ์ํ ๊ฒฝ์ฐ(์ต๋จ ๊ฒฝ๋ก ๊ตฌํ๊ธฐ ๋ฑ)์ ์ ๋ฆฌํฉ๋๋ค.
๊ทธ๋ํ์ ๋ชจ๋ ๋ ธ๋๋ฅผ ํ์ํด์ผ ํ๋ค๋ฉด DFS๊ฐ ๋ ์ข์ ๋ฐฉ๋ฒ์ผ ์ ์์ต๋๋ค.
Reference
Graphs: breadth-first search | freeCodeCamp
Last updated