Computer Science
DFS 깊이 우선 탐색의 원리와 활용
Balang
2025. 4. 16. 16:53
728x90
DFS란?
Depth-First Search (DFS)는 그래프나 트리에서
한 방향으로 끝까지 파고들었다가, 갈 곳이 없으면 되돌아오는 탐색 알고리즘입니다.
즉, 가장 깊은 노드부터 먼저 탐색
DFS가 왜 중요한가?
- 트리 구조 분석
- 백트래킹 문저 (ex: N-Queen, 조합 탐색)
- 경로 찾기 (모든 가능한 경로를 보고 싶을 때)
- 싸이클 탐지
DFS 두가지 구현
1) 재귀 (가장 직관적)
def dfs_recursive(graph, v, visited):
visited[v] = True
print(v, end=' ')
for neighbor in graph[v]:
if not visited[neighbor]:
dfs_recursive(graph, neighbor, visited)
2) 스택 (명시적 구현)
def dfs_stack(graph, start):
visited = [False] * len(graph)
stack = [start]
while stack:
v = stack.pop()
if not visited[v]:
visited[v] = True
print(v, end=' ')
stack.extend(reversed(graph[v]))
DFS 동작 순서 예시 (재귀)
그래프:
graph = {
1: [2, 3],
2: [4, 5],
3: [],
4: [],
5: []
}
visited = [False] * 6
dfs_recursive(graph, 1, visited)
# 1 2 4 5 3
깊이 우선 → 1 → 2 → 4 → 5 → 3
DFS 실전 활용 예시
백트래킹 (조합/순열 찾기)
def backtrack(path, nums):
if not nums:
print(path)
return
for i in range(len(nums)):
backtrack(path + [nums[i]], nums[:i] + nums[i+1:])
싸이클 탐지
def has_cycle(graph, v, visited, parent):
visited[v] = True
for neighbor in graph[v]:
if not visited[neighbor]:
if has_cycle(graph, neighbor, visited, v):
return True
elif neighbor != parent:
return True
return False
DFS 시간 복잡도
- 시간복잡도: O(V + E)
(V: 노드 수, E: 간선 수) - 공간복잡도: O(V) + 재귀 깊이
상황 별 정리
상황 | DFS 활용 이유 |
가능한 모든 경우의 수 탐색 | 백트래킹 기반 |
트리 구조 순회 | DFS가 자연스럽게 사용됨 |
재귀 함수로 직관적 구현 | 파이썬에 적합 |
방문 순서보다 경로에 집중 | DFS가 더 적합 |
정리
항목 | 설명 |
이름 | DFS (Depth-First Search) |
탐색 방식 | 깊게 들어간 후 되돌아오기 |
자료구좋 | 스택 (또는 재귀) |
시간복잡도 | O(V + E) |
주요 활용 | 백트래킹, 경로 찾기, 싸이클 탐지 등 |
728x90
반응형