1. BFS (Breadth-First Search)
BFS๋ ์์ ๋
ธ๋์์๋ถํฐ ๊ฐ๊น์ด ๋
ธ๋๋ถํฐ ์ฐจ๋ก๋ก ๋ฐฉ๋ฌธํ๋ ์๊ณ ๋ฆฌ์ฆ์
๋๋ค.
๋ณดํต ํ(Queue, FIFO: First-In, First-Out)๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ต๋จ ๊ฒฝ๋ก, ๋ ๋ฒจ ์ํ ๋ฑ์ ์ ์ฉํฉ๋๋ค.
function bfsWithVisited(start, getNeighbors) {
const queue = [start];
const visited = new Set();
visited.add(start);
console.log("์ด๊ธฐ visited:", Array.from(visited));
while (queue.length > 0) {
const current = queue.shift(); // ํ์์ ๊ฐ์ฅ ์์ ์์๋ฅผ ๊บผ๋
console.log("ํ์ฌ ์ฒ๋ฆฌ ๋
ธ๋:", current);
// ํ์ฌ ๋
ธ๋์ ์ด์๋ค์ ์ํ
for (const neighbor of getNeighbors(current)) {
if (!visited.has(neighbor)) {
visited.add(neighbor);
queue.push(neighbor);
console.log(`์๋กญ๊ฒ ๋ฐฉ๋ฌธ: ${neighbor} -> visited:`, Array.from(visited));
}
}
}
return visited;
}
// ์์ ๊ทธ๋ํ (์ธ์ ๋ฆฌ์คํธ ํํ)
const graph = {
A: ['B', 'C'],
B: ['A', 'D', 'E'],
C: ['A', 'F'],
D: ['B'],
E: ['B', 'F'],
F: ['C', 'E']
};
// BFS ์คํ ์์
console.log("BFS ๋ฐฉ๋ฌธ ๊ฒฐ๊ณผ:");
bfsWithVisited('A', node => graph[node]);
// ์์ BFS ๋ฐฉ๋ฌธ ์์: A → B → C → D → E → F
์ด๊ธฐ ์ํ์์ ์์ ๋
ธ๋ A๋ฅผ ํ์ visited์ ์ถ๊ฐํฉ๋๋ค.
ํ์์ ํ๋์ฉ ๊บผ๋ด๋ฉฐ, ํด๋น ๋
ธ๋์ ์ด์ ์ค ์์ง ๋ฐฉ๋ฌธํ์ง ์์ ๋
ธ๋๋ฅผ ํ์ ์ถ๊ฐํฉ๋๋ค.
๋ฐฉ๋ฌธ ์ํ(visited)๋ Set์ผ๋ก ๊ด๋ฆฌํ์ฌ ์ค๋ณต ๋ฐฉ๋ฌธ์ ๋ง์ต๋๋ค.
2. DFS (Depth-First Search)
DFS๋ ํ ๊ฒฝ๋ก๋ฅผ ๊ฐ๋ฅํ ๊น๊ฒ ํ์ํ ํ, ๋ ์ด์ ์งํํ ์ ์์ผ๋ฉด ๋ฐฑํธ๋ํนํ์ฌ ๋ค๋ฅธ ๊ฒฝ๋ก๋ฅผ ํ์ํฉ๋๋ค.
์ฌ๊ท๋ ์คํ(Stack, LIFO: Last-In, First-Out)์ ์ฌ์ฉํ์ฌ ๊ตฌํํ ์ ์์ต๋๋ค.
๊ฒฝ๋ก ํ์, ๋ฐฑํธ๋ํน, ์ฌ์ดํด ๊ฐ์ง ๋ฑ์ ์ ์ฉํฉ๋๋ค.
2.1. ์ฌ๊ท ๊ธฐ๋ฐ DFS : ํจ์ ํธ์ถ ์คํ์ ์ฌ์ฉํด ๊น์ด ์ฐ์ ํ์์ ์์ฐ์ค๋ฝ๊ฒ ๊ตฌํํฉ๋๋ค.
function dfsRecursiveWithVisited(node, getNeighbors, visited = new Set()) {
visited.add(node);
console.log("ํ์ฌ ๋ฐฉ๋ฌธ ๋
ธ๋:", node, "-> visited:", Array.from(visited));
for (const neighbor of getNeighbors(node)) {
if (!visited.has(neighbor)) {
dfsRecursiveWithVisited(neighbor, getNeighbors, visited);
}
}
return visited;
}
// DFS ์คํ ์์ (์ฌ๊ท ๋ฐฉ์)
console.log("DFS (์ฌ๊ท) ๋ฐฉ๋ฌธ ๊ฒฐ๊ณผ:");
dfsRecursiveWithVisited('A', node => graph[node]);
// ์์ DFS ๋ฐฉ๋ฌธ ์์ (์์): A → B → D → E → F → C
// (ํ์ ์์๋ getNeighbors ํจ์์ ๋ฐํ ์์์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์์)
2.2. ์คํ ๊ธฐ๋ฐ DFS: ๋ช ์์ ์ธ ์คํ์ ์ฌ์ฉํ์ฌ ํ์ ์ ์ถ(LIFO) ๋ฐฉ์์ผ๋ก, ๋ง์ง๋ง์ ์ถ๊ฐ๋ ๋ ธ๋๋ถํฐ ์ฒ๋ฆฌํฉ๋๋ค.
function dfsStack(start, getNeighbors) {
const stack = [start];
const visited = new Set();
while (stack.length > 0) {
const current = stack.pop(); // ์คํ์์ ๋ง์ง๋ง ์์๋ฅผ ๊บผ๋ (LIFO)
if (!visited.has(current)) {
visited.add(current);
console.log("ํ์ฌ ๋ฐฉ๋ฌธ ๋
ธ๋:", current, "-> visited:", Array.from(visited));
// ์ด์๋ค์ ์คํ์ ์ถ๊ฐ (์์๋ ์ด์ ๋ฐฐ์ด ์์์ ๋ฐ๋ผ ๋ค๋ฅผ ์ ์์)
for (const neighbor of getNeighbors(current)) {
if (!visited.has(neighbor)) {
stack.push(neighbor);
}
}
}
}
return visited;
}
// DFS ์คํ ์์ (์คํ ๋ฐฉ์)
console.log("DFS (์คํ) ๋ฐฉ๋ฌธ ๊ฒฐ๊ณผ:");
dfsStack('A', node => graph[node]);
// ์์ DFS ๋ฐฉ๋ฌธ ์์ (์์): A → C → F → E → B → D
// (ํ์ ์์๋ ์ด์์ ์ถ๊ฐ ์์์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์์)
๋๊ธ