DFS란?
DFS(Depth-First Search, 깊이 우선 탐색) 는 그래프나 트리를 탐색할 때 한 길을
끝까지 파고든 뒤, 막다른 곳에서 되돌아와 다른 길을 탐색하는 방식입니다.
미로에서 한쪽 벽을 손으로 짚고 갈 수 있는 데까지 간 다음, 막히면 갈림길로 돌아와
다른 길을 시도하는 것과 같습니다.
1. 그래프 표현부터
탐색하려면 먼저 그래프를 메모리에 담아야 합니다. 가장 흔한 표현은 인접 리스트
입니다 — 각 정점마다 "이어진 정점들의 목록"을 둡니다.
정점 1 → [2, 3]
정점 2 → [1, 4]
정점 3 → [1]
정점 4 → [2]
간선이 적은 희소 그래프에서는 인접 행렬(\(O(V^2)\) 메모리)보다 인접 리스트
(\(O(V + E)\))가 효율적입니다.
2. DFS의 동작
한 정점에서 출발해:
- 현재 정점을 방문 표시한다.
- 이어진 정점 중 아직 방문 안 한 곳으로 깊이 들어간다(재귀).
- 더 갈 곳이 없으면 되돌아온다.
이 "끝까지 갔다가 되돌아오는" 흐름이 재귀와 완벽히 맞아떨어집니다. 그래서 DFS는
보통 재귀로 구현합니다.
3. 방문 표시가 생명
방문 배열을 안 쓰면 같은 정점을 무한히 오갈 수 있습니다(사이클). 방문하면 즉시
표시하고, 표시된 곳은 다시 안 들어간다 — 이것이 DFS의 정확성과 종료를
보장합니다. 각 정점을 한 번씩만 방문하므로 전체 복잡도는 \(O(V + E)\)입니다.
4. DFS로 푸는 문제들
| 문제 | DFS의 역할 |
|---|---|
| 연결 요소 세기 | 한 번의 DFS = 한 덩어리 |
| 경로 존재 여부 | 출발에서 도착에 닿는가 |
| 사이클 탐지 | 탐색 중인 정점을 다시 만나면 사이클 |
| 위상 정렬 | DFS 종료 순서의 역순 |
| 미로 탐색/영역 칠하기(flood fill) | 격자를 그래프로 보고 DFS |
특히 격자(2차원 배열)에서 "연결된 영역의 크기/개수"를 구하는 flood fill이 가장
자주 나옵니다.
5. DFS vs BFS
둘 다 모든 정점을 \(O(V+E)\)에 방문하지만 성격이 다릅니다.
| DFS | BFS | |
|---|---|---|
| 자료구조 | 스택(재귀) | 큐 |
| 진행 방향 | 깊이 우선 | 너비 우선 |
| 최단 거리 | 보장 안 됨 | 보장됨(무가중치) |
| 적합 | 경로·연결성·사이클 | 최단 거리·레벨 |
"최단 거리"가 필요하면 BFS, "갈 수 있나/연결됐나/모든 경로"면 DFS가 자연스럽습니다.
정리
DFS는 한 길을 끝까지 파고들고 막히면 되돌아오는 탐색입니다. 인접 리스트로
그래프를 담고, 방문 표시로 사이클을 막으며, 재귀로 간결하게 구현합니다.
연결 요소·경로·사이클·flood fill의 기본 도구입니다.