BFS와 DFS: 그래프 탐색의 두 기초 알고리즘
그래프 탐색은 많은 양의 데이터 중에서 특정한 정보를 찾아내는 과정을 포함하며, 이 과정에서 자주 사용되는 두 가지 대표적인 알고리즘이 바로 너비 우선 탐색(BFS, Breadth-First Search)과 깊이 우선 탐색(DFS, Depth-First Search)입니다. 이 글에서는 두 알고리즘의 차이점과 각각의 특성, 활용 방법 등에 대해 다뤄보겠습니다.

그래프와 탐색
그래프(Graph)란 노드(Node)와 간선(Edge)으로 구성된 자료구조로, 서로 연결된 데이터의 집합을 나타냅니다. 이러한 그래프 구조에서 BFS와 DFS는 방문할 노드를 선택하는 방식에 따라 크게 두 가지로 나눌 수 있습니다. 각 알고리즘은 탐색의 방식이 상이하기 때문에 사용할 때 최적의 상황을 고려하는 것이 중요합니다.
BFS(너비 우선 탐색)
BFS는 그래프의 근처에 있는 노드부터 우선적으로 탐색하는 기법입니다. 이 방식은 큐(Queue) 자료구조를 사용하여 구현됩니다. BFS는 주로 다음과 같은 상황에서 유용합니다:
- 최단 경로를 찾아야 할 때
- 모든 경로를 동시적으로 탐색하고자 할 때
- 넓은 영역의 탐색이 필요한 경우
BFS의 작동 방식은 다음과 같습니다:
- 탐색할 시작 노드를 큐에 삽입하고 방문 처리합니다.
- 큐에서 노드를 꺼내 그 노드의 인접 노드 중 방문하지 않은 노드를 모두 큐에 추가하고 방문 처리합니다.
- 이 과정을 더 이상 수행할 수 없을 때까지 반복합니다.
BFS의 구현
BFS는 파이썬에서 deque 모듈을 활용해 구현할 수 있습니다. 아래는 BFS의 간단한 구현 예시입니다:
from collections import deque def bfs(graph, start): visited = [False] * len(graph) queue = deque([start]) visited[start] = True while queue: node = queue.popleft() print(node, end=' ') for neighbor in graph[node]: if not visited[neighbor]: visited[neighbor] = True queue.append(neighbor) graph = [[], [2, 3], [1, 4], [1, 5], [2], [3]] bfs(graph, 1)
DFS(깊이 우선 탐색)
DFS는 가능한 깊이까지 노드를 탐색하는 방법입니다. 이 알고리즘은 스택(Stack) 또는 재귀 호출을 통해 구현됩니다. DFS는 다음과 같이 활용될 수 있습니다:
- 모든 노드를 깊이 있게 탐색하고자 할 때
- 경로의 특징을 기록해야 하는 경우
- 특정 조건을 만족하는 해를 찾아야 할 때
DFS의 작동 방식은 다음과 같습니다:
- 시작 노드를 스택에 추가하고 방문 처리합니다.
- 유효한 인접 노드가 있다면 그 노드를 스택에 추가하고 방문합니다.
- 더 이상 방문할 노드가 없다면 스택에서 노드를 꺼냅니다.
- 이 과정을 반복합니다.
DFS의 구현
DFS의 기본적인 구현은 다음과 같습니다:
def dfs(graph, node, visited): visited[node] = True print(node, end=' ') for neighbor in graph[node]: if not visited[neighbor]: dfs(graph, neighbor, visited) graph = [[], [2, 3], [1, 4], [1, 5], [2], [3]] visited = [False] * len(graph) dfs(graph, 1, visited)
BFS와 DFS의 차이점
BFS와 DFS는 각기 다른 방식으로 그래프를 탐색하므로 사용해야 할 상황도 다릅니다. 다음은 이 두 알고리즘의 주요 차이점입니다:
- 탐색 방식: BFS는 가까운 노드부터, DFS는 깊이 있는 노드를 먼저 탐색합니다.
- 자료구조: BFS는 큐를, DFS는 스택(혹은 재귀)을 사용합니다.
- 최단 경로: BFS는 최단 경로를 보장하는 반면, DFS는 그렇지 않습니다.
효율적인 활용
각 알고리즘의 특성을 이해하고 상황에 맞는 선택을 하는 것이 중요합니다. 예를 들어, 경로를 찾는 문제에서는 BFS를 선택하는 것이 더 유리할 수 있으며, 다양한 경로를 탐색해야 할 경우 DFS가 적합할 수 있습니다.
BFS와 DFS는 코딩 테스트 및 알고리즘 문제해결에서 빈번하게 등장하므로, 두 알고리즘의 구현 방식과 작동 원리를 숙지해 두는 것이 좋습니다.

결론
그래프 탐색에서 BFS와 DFS는 각기 다른 접근 방식을 제공하며, 이해하고 활용할 수 있다면 많은 문제를 효과적으로 해결할 수 있습니다. 각 알고리즘의 특징을 잘 활용하여 최적의 솔루션을 도출하시길 바랍니다.
자주 묻는 질문 FAQ
BFS와 DFS의 주요 차이점은 무엇인가요?
BFS는 가까운 노드부터 탐색하는 반면, DFS는 더 깊은 노드를 먼저 방문합니다. 이 두 알고리즘은 사용하는 자료구조도 다릅니다; BFS는 큐를 사용하고 DFS는 스택 또는 재귀를 통해 구현됩니다.
어떤 상황에서 BFS를 사용하는 것이 좋나요?
BFS는 최단 경로를 찾거나 여러 경로를 동시에 탐색할 필요가 있을 때 유용합니다. 특히 연결된 노드가 많은 경우 넓은 영역을 효과적으로 탐색할 수 있습니다.
DFS를 활용해야 할 상황은 어떤 경우인가요?
DFS는 특정 조건을 만족하는 해를 찾거나 모든 노드를 깊이 있게 탐색해야 할 때 적합합니다. 복잡한 경로 특성을 추적해야 할 때도 이 방법이 유리합니다.