Code
자바스크립트에서의 BFS와 DFS
haeunkim.on
2025. 3. 3. 20:56
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
// (탐색 순서는 이웃의 추가 순서에 따라 달라질 수 있음)
반응형