깊이 우선 탐색 (DFS)란?
Depth-First Search (DFS)는 트리와 그래프 데이터 구조를 탐색하는 기본 알고리즘입니다. 각 경로를 가능한 한 깊게 탐색한 후 백트래킹하는 방식으로 동작하여 경로 찾기, 위상 정렬, 사이클 검출 등에 적합합니다.
DFS 알고리즘 설명
DFS는 재귀(암시적 호출 스택)나 명시적 스택 자료구조를 사용하여 구현할 수 있습니다. 핵심 아이디어는 다음과 같습니다:
- 루트(또는 임의의 시작 노드)에서 시작합니다.
- 노드를 방문하고 방문 표시합니다.
- 방문하지 않은 인접 노드를 재귀적 또는 반복적으로 방문합니다.
알고리즘 단계 (이진 트리 - 재귀)
- 현재 노드를 방문합니다.
- 왼쪽 서브트리를 재귀적으로 탐색합니다.
- 오른쪽 서브트리를 재귀적으로 탐색합니다.
알고리즘 단계 (일반 그래프 - 스택 기반)
- 시작 노드를 스택에 넣고 방문 표시합니다.
- 스택이 비어있지 않은 동안:
- 스택에서 노드를 꺼냅니다.
- 노드를 처리합니다.
- 방문하지 않은 인접 노드를 모두 스택에 추가하고 방문 표시합니다.
Python 예제 코드
1. 이진 트리에서 DFS (재귀)
class TreeNode:
def __init__(self, value):
self.val = value
self.left = None
self.right = None
def dfs_binary_tree(node):
if not node:
return
print(node.val)
dfs_binary_tree(node.left)
dfs_binary_tree(node.right)
# 예제 실행
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
dfs_binary_tree(root)
실행결과:
1
2
4
5
3
2. 일반 그래프에서 DFS (반복적)
def dfs_graph(graph, start):
visited = set()
stack = [start]
while stack:
node = stack.pop()
if node not in visited:
print(node)
visited.add(node)
for neighbor in reversed(graph[node]):
if neighbor not in visited:
stack.append(neighbor)
# 예제 실행
graph = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': ['F'],
'F': []
}
dfs_graph(graph, 'A')
실행결과:
A
B
D
E
F
C
시간 및 공간 복잡도 분석
이진 트리
- 시간 복잡도: $O(n)$ (노드 수 n 만큼 방문)
- 공간 복잡도: $O(h)$ (트리 높이 h 만큼 재귀 스택 공간 필요)
일반 그래프
- 시간 복잡도: $O(V + E)$ (정점 수 V, 간선 수 E)
- 공간 복잡도: $O(V)$ (방문한 노드 및 스택 저장용)
결론
DFS는 다양한 문제를 해결하는 데 매우 강력하고 유연한 방법입니다. 깊은 경로 탐색이나 백트래킹 기반 문제를 해결할 때 특히 효과적이며, 알고리즘 설계에 있어 필수적인 도구입니다.
참고 문헌
'Algorithm' 카테고리의 다른 글
코사인 유사도와 코사인 거리 개념 및 딥러닝에서의 활용 | PyTorch 예제 포함 (0) | 2025.04.30 |
---|---|
BFS(너비 우선 탐색) 알고리즘: 동작 원리와 Python 코드 구현 (0) | 2025.04.29 |
A* 탐색 알고리즘 - Python 예제와 함께 자세한 설명 (1) | 2025.04.29 |
검색 알고리즘: 상세 설명과 Python 구현 (0) | 2025.04.28 |
SIMD와 MIMD 차이점 쉽게 설명 (0) | 2025.04.23 |