Ch.7 그래프
DFS — 깊이 우선 탐색, 끝까지 파고들기
미로에서 길을 찾는 가장 직관적인 방법
미로에 들어섰습니다. 갈림길에서 항상 왼쪽부터 선택하고, 막다른 길이면 되돌아갑니다. 이것이 바로 DFS(깊이 우선 탐색)입니다.
되돌아갈 때 어디까지 돌아가야 하지? 이미 방문한 곳을 다시 가면?
스택(또는 재귀 호출 스택)이 되돌아갈 위치를 기억하고, visited 집합이 재방문을 막습니다.
핵심 개념
DFS(깊이 우선 탐색)
한 경로를 끝까지 탐색한 뒤 되돌아가는 방식
백트래킹(Backtracking)
막다른 길에서 이전 갈림길로 되돌아가기
핵심 내용
그래프 탐색의 기본 무기, DFS를 배웁니다
DFS는 한 길을 끝까지 가봅니다. 막히면 돌아와서 다른 길을 시도합니다
DFS의 핵심 규칙: 더 깊이 갈 수 있으면 가고, 못 가면 되돌아간다
DFS를 재귀로 구현하면 놀랍도록 간결합니다
def dfs(graph, node, visited=None):
if visited is None:
visited = set()
visited.add(node) # 1. 현재 노드 방문
print(node, end=' ') # 2. 처리
for neighbor in graph[node]: # 3. 이웃 탐색
if neighbor not in visited:
dfs(graph, neighbor, visited) # 4. 재귀
return visited
# 사용
graph = {'A':['B','C'], 'B':['A','D'], 'C':['A','D'], 'D':['B','C']}
dfs(graph, 'A') # A B D CDFS 재귀 템플릿 (암기!) 1. `visited.add(node)` — 방문 표시 2. 현재 노드 처리 3. `for neighbor in graph[node]` — 이웃 순회 4. `if neighbor not in visited` → 재귀 호출
이 4줄 패턴이 면접 그래프 문제의 80%를 해결합니다. 반드시 외우세요!
재귀가 깊어지면 스택 오버플로. 반복문 DFS도 알아야 합니다
def dfs_iterative(graph, start):
visited = set()
stack = [start]
while stack:
node = stack.pop() # 스택에서 꺼냄
if node in visited:
continue
visited.add(node)
print(node, end=' ')
for neighbor in graph[node]:
if neighbor not in visited:
stack.append(neighbor)
return visited스택에 넣고 → 꺼내고 → 방문 안 했으면 처리 → 이웃을 스택에 추가. BFS와 딱 한 가지만 다릅니다 — stack vs queue
재귀 DFS: 코드가 짧고 직관적 반복 DFS: 스택 오버플로 걱정 없음
재귀 DFS가 어떤 순서로 노드를 방문하는지 추적합니다
방문 순서: A → B → D → (되돌아감) → C 깊이 우선으로 끝까지 갔다 돌아옵니다
DFS의 대표 활용 — 연결 요소(Connected Component) 개수 구하기
def count_components(n, edges):
graph = defaultdict(list)
for u, v in edges:
graph[u].append(v)
graph[v].append(u)
visited = set()
count = 0
for node in range(n):
if node not in visited:
dfs(graph, node, visited)
count += 1 # DFS 한 번 = 연결 요소 1개
return count
# 0-1-2 3-4 → 2개의 연결 요소
print(count_components(5, [(0,1),(1,2),(3,4)])) # 2DFS를 호출한 횟수 = 연결 요소의 개수. 이 패턴은 Number of Islands에도 그대로 적용됩니다!
DFS에서 visited를 사용하지 않으면 어떤 문제가 발생할까요?
재귀 DFS의 시간 복잡도는 O(V + E)이다
DFS 정복 완료!
핵심 용어
DFS
Depth-First Search — 깊이 우선 탐색
스택/재귀
DFS의 핵심 자료구조 — 되돌아갈 위치 기억
visited
이미 방문한 노드를 기록하는 set
정리 노트
깊이 우선 탐색 (DFS)
핵심 패턴
- 재귀 DFS
- `visited.add(node)` → 이웃 순회 → 재귀
- 반복 DFS
- stack.pop() → 방문 처리 → 이웃 push
- 시간 복잡도
- O(V + E)
필수 기억
- visited
- 없으면 사이클에서 무한 루프
- 연결 요소
- DFS 호출 횟수 = 연결 요소 개수
DFS 4줄 템플릿: visited.add → 처리 → for neighbor → if not visited → 재귀
시각 자료
핵심 정리
- 1DFS = 한 길을 끝까지 탐색 후 되돌아가기
- 2재귀 DFS 4줄 패턴은 반드시 암기
- 3visited 없으면 무한 루프, DFS 호출 횟수 = 연결 요소 수
퀴즈와 인터랙션으로 더 깊이 학습하세요
play_circle인터랙티브 레슨 시작